Version 4 (modified by Waldemar Kornewald, 9 years ago) (diff)


Here we collect the high-level refactorings required for non-sql (or non-relational) backends. Also see the specific backend docs for details: AppEngine


The query classes defined in this module are used by QuerySet and Model, but it's not possible to override the subquery classes.

TODO: Is this necessary, at all? Probably yes if you want a clean port.


References: Primary keys

At least on App Engine the primary key itself won't be sufficient to retrieve a model if you use entity groups. In that case you need the whole path (parent + primary key) to uniquely identify the object. Since this is an App Engine feature that probably can't be mapped to other DB types we just need to support it transparently at the reference fields level. Everywhere else we can assume that the user knows about the parent requirement.


Multi-table inheritance

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 because not all backends make that distinction, at all. 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).


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).


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.

Back to Top