|Version 2 (modified by wkornewald, 6 years ago) (diff)|
Here we collect the refactorings required for non-sql (or non-relational) backends.
The query classes defined in this module are used by QuerySet and Model, but it's not possible to override the subquery classes.
TODO: Check if there is any SQL-related code that needs to be more abstract (as_sql() appears in a few places, but maybe it doesn't affect the port).
In the current implementation, multi-table inheritance requires reads and writes across multiple tables. On non-relational DBs this has to be solved differently. For example, with a ListField type you could store all models which you derived from (inspired by PolyModel). On App Engine this adds deeper composite indexes which is a problem when filtering against multiple ListFields combining that with inequality filters or results ordering (exploding indexes). Thus, this should only be used at the second inheritance level (seen from Model base class).
The distinction between insert and update should be done by sql.Query. The check whether the pk already exists (which is part of the distinction) should be moved out, too.
model.delete() collects all referenced objects using _collect_sub_objects(). For non-sql backends this is not always possible for example when running in a transaction on app engine (only entities in the same entity group can be fetched from the datastore). Additionally delete() calls delete_objects() which makes use of DeleteQuery and UpdateQuery imported from sql.subqueries. There should be a way to override these query classes.
Not all backends support transactions, at all (e.g., SimpleDB). Some (e.g., App Engine) only support transactions similar to "SELECT ... FOR UPDATE" (which isn't exactly the same as @commit_on_success because it really locks items for read/write access). Not all backends support a BEGIN/END TRANSACTION operation, but only provide an interface for calling a function transactionally (like the @commit_on_success decorator).
Since on App Engine locking transactions can't access rows outside of the current entity group the post_save/_delete signal handlers aren't sufficient (though, sometimes they're exactly what you need). We really need signals for getting notified of "save" and "delete" after a locking transaction has finished.
TODO: Let's wait for App Engine to support its new bookmarks mechanism (key-based pagination doesn't work in all situations).
On App Engine you can only retrieve the first 1000 query results. There needs to be support for "bookmarks" which mark the next starting point.
On SimpleDB you can directly retrieve the bookmark of the Nth item and run the query from there. TODO(mitch?): Find out if this is efficient (even for millions of items) or if it's better to provide bookmarks at a higher level.