DjangoCon: Inside the ORM
Malcom Tredinnick gave an awesome presentation about the Django ORM.
The code for the ORM is located in django/db with juicy bits in the following locations:
django/db/models/query.py (public queryset API)
django/db/models/sql/* (Public API->SQL conversion. Deep dark internals. Does’t know DB, knows SQL)
django/db/backends/* (Individual DB wrappers, third-party wrappers possible. This is where you actually talk to the DB). See (dummy or mysql dir for examples)
The different pieces in depth
Blog.objects.filter(owner=user) = [model, manage, QuerySet method]
Model Manages:
inherit from django.db.models.Manager, ideal for extra methods that act on the whole table at once, not just one record, usually wraps/proxies public querySet methos, has method called get_query_set() which returns QuerySet (QuerySet.all)
QuerySets:
django.db.models.query.QuerySet
Every time you call a method on a QuerySet it returns a copy (clone) of that QuerySet (side effect free?) For example every time you call filter on a query set you get a different queryset.
Query
django.db.models.sql.query.Query, an attribute of QuerySet, holds the internal state of the current query, knows how to produce SQL. This is where you implement something that knows how to speak to MySQL, or CouchDB or Hadoop for example. (Aka class from Hell, almost every data-structure known to man used here). AsSQL is when state is rewritten into SQL. This is a change from before QuerySet Refactor landed in trunk where the internal representation for everything was strings.
Every method of QuerySet updates the Query (calls method on Query).
Query.results_iter() is how the results end up from the DB back into Python objects, reconstructing Python objects happens in various other Query methods: Query.select_related, Query.extra_select…etc
Looking inside the Query. Query.add_filter() is the guts — the place to start when trying to grok the Query class. Query.setup_joins() converts filter/exclude into table joins. Query.join() responsible for joining a pair of tables
Recap on flow/organization: Manager->QuerySet->Query
Customization:
Custom Managers (Easy)
Custom QuerySet (Not so Easy)
–> (Some example QuerySet) ValuesQuerySet, DateQuerySet, EmptyQuerySet
Custom Query (Not so Easy)
GeoDjango for example has to use very different types of query.
Note to self: I’m wondering how(or even IF) one would use Django’s ORM for a Solr-backend for intergrated search via a DJango ORM model.
Filed under: Programming




