SQL - Object-Relational Frameworks =================================== - Tight integration between application logic and the database - Describe the database model as an object-oriented class description - Write queries not in SQL but directly in the programming language - Create tools that are DB agnostic - Main focus: - Most web based db programming requires a number of tasks that are highly repetitive and common (and not as glamarous as SQL programming). Examples: data validation, input sanitization, etc. - Frameworks are designed to provide common tools for these tasks so that the programs are easy and fast to develop. Examples: authentication tools, password/email data types - Many commonly used examples: - Django for Python: Disqus, bitbucket, instagram, pinterest - Ruby on Rails or Grail for Ruby: airbnb, ask.fm, couchsurfind, github - Hibernate for Java - DataObjects.Net for .NET - SQLAlchemy and Flask for Python - We will base the examples below on Django. MVC/T: Models, Views and Templates (or Controllers) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Build a full-stack application by defining the different components - Models are the data models of the tables that will be stored in the database - Views are the HTML pages that you will see, loading data from models and executing functions for certain actions (like button clicks) - Controller is the application logic: that tells you what will happen when certain actions are executed: run queries, db changes and render new HTML pages - Often views are a mix of HTML/Python and Javascript for active elements Models ~~~~~~~~~ - Define your DB tables using an object-relational paradigm - Each table is a class, storing objects of this type :: class Student(models.Model): name = models.CharField(max_length=255) email = models.CharField(max_length=255) address = models.CharField(max_length=255) year = models.IntegerField() gpa = models.FloatField() major = models.CharField(max_length=2) - The table associated will be called `Students` and will have a primary key `id` by default (can be overridden). Views ~~~~~~~~~~~~~~~ - Views can query these objects using simple queries: :: def index(request): students = Student.objects.all() return render(request, 'index.html', {'students':students,}) - Templates can render these objects using simple loops: :: Complex Models ~~~~~~~~~~~~~~~~~~~ - Foreign keys: :: class Department(models.Model): name = models.CharField(max_length=255) office = models.CharField(max_length=40) phone = models.CharField(max_length=12) class Major(models.Model): name = models.CharField(max_length=255) department = models.ForeignKey(Department, on_delete.Models.CASCADE) - Allows for the querying and retrieval of models through the foreign keys: :: departments = Deparment.objects.all() majors = Major.objects.all() for major in majors: print (major.department.name) majors = Major.objects.filter(department__name = 'Computer Science') Querying ~~~~~~~~~ - Most queries are simple filter statements over single relations or relations obtained through foreign keys. - Does not require you to know full SQL. - Most application function is easily mapped to CRUD operations (create, read, update and delete) that are easily supported - Be careful if your join is different than what the foreign key implies - Be careful about how much data is read for each object and when: for deep nested structures, does it read the whole hierarchy? Summary --------- - OR frameworks are quite powerful and provide a lot of functionality off the shelf - DRY principle: do not repeat yourself: write code once and use many times - For the tools, you pay a price: restrictive models and naming conventions Example: lack of support for multi-attribute keys - You need to be careful if your query is best handled by the tool and by custom SQL - Same as application logic: is it better to write functions in the views or a stored procedure in the back end.