15. QuerySet
This is the top layer of query state. From here on out
it’s like an onion.
Not backend specific.
_db
_result_cache
_iter
query
16. Query
Right now this holds all state for a query.
It’s semi-backend specific. Right now there’s one, and
it’s specific to SQL backends.
Computes most JOINS, aggregates, etc.
Translates Q objects into Where objects.
17. The Query Problem
It’s something of a lossy translation.
Translating filter(), values(), and other calls into internal
datastructures is lossless with respect to the database
being used, but not with respect to other databases.
If you’ve got all SQL databases you’re fine, but if you
mix in a non-relational DB you’ve got problems.
More on this later.
18. SQLCompiler
Takes a Query and a connection and turns it into SQL
(and executes it).
This also does some computation of joins (for
select_related).
This is the totally backend specific part (only part that
knows about the actual connection and database).
The rest of the chain just *assumes* a SQL db.
19. django.db.backends.*
This is where backends live.
Not super exciting.
A bunch of flags and methods to control very small
parts of SQL creation.
Also introspection, creation, and shell.
20. You call methods on a QuerySet
Which calls methods on a Query
Which mutates some datastructures
You evaluate a QuerySet
Which asks it’s Query for a Compiler
Which generates some SQL
Which calls some methods on the backend
Which gets a cursor and evaluates it
22. Query thinks in terms of
SQL
It chooses between join types
it generates table aliases
it splits filters between HAVING and WHERE
and probably some other stuff
23. Why is this an issue
How do I ask a MongoDBCompiler to compile a LEFT
OUTER JOIN vs. an INNER JOIN?
Or a HAVING vs a WHERE?
These concepts don’t map cleanly, so the translation is
lossy across backends
29. Make Query do less
Instead of generating two trees of WHERE and
HAVING, generate a single tree of filters.
Don’t generate JOINs at all.
Push that all down to the compiler.
30. Make SQLCompiler do more
Generate all JOINs
Split filter tree into HAVING vs WHERE
Can generate more efficient JOINs with global
knowledge.
Probably makes it easier to do fix some other ORM
bugs.
31. Plan of action
Change the ORM up
Build MongoDB prototype backend
???
Profit