On Fri, Jan 15, 2010 at 3:55 AM, Russell Keith-Magee <[email protected]> wrote: > And to be clear - a solid proposal isn't just "merge this branch". A > patch/branch is one way to prove that you have thought about the > problem in detail, but you also need to provide the discussion and > description necessary to explain the nature of and reasoning behind > the changes you want to make.
OK, I think I've found a better way to get very non-relational backend support integrated with minimal changes to Django. The current patch is very simple and it's not based on QueryData, but it already supports the same feature set as our previous port. It's not yet sufficient for emulating JOINs and maybe a few other "advanced" features, but it looks like sql.Query and SQLCompiler would only need minor modifications to be abstract enough for emulating advanced features with nonrel DBs. Anyway, this can be added once we've discussed whether the current solution is good enough. The idea is to just use the SQLCompiler backend API and let the nonrel backends interpret sql.Query.where and the other query attributes. This required a few small changes to sql.Query and SQLCompiler. The patch is this commit: http://bitbucket.org/wkornewald/django-nonrel/changeset/71117e43ae33/ My reasoning behind the patch is the following: 1. Nonrel DBs don't distinguish between INSERT and UPDATE On such DBs Model.save_base() shouldn't check if an entity already exists. Instead, it should just always INSERT. For this I added connection.features.distinguishes_insert_from_update. 2. Deleting related objects can be too costly on non-relational DBs For this I added connection.features.supports_deleting_related_objects. If it's False no related objects will be deleted. Ideally, the backend should be able to delegate this job to a background task. This is planned. 3. Multi-table inheritance needs JOINs For this I added connection.features.supports_multi_table_inheritance. If it's False Django will reject to save this model or run queries on this model using that connection. In the future, at least single inheritance could be emulated with a ListField type. On App Engine multiple inheritance support would require lots of custom datastore indexes and could lead to exploding indexes. We can discuss this later. 4. sql.Query.has_results() used a trick that only works with SQL I moved some of the code to SQLCompiler, so the backend can override it. 5. We need transactions which lock rows I added a GAE-specific @commit_locked transaction decorator. This should be moved into the backend layer, of course. I'd just like to know if this is an option for 1.3 or not. On SQL this would be SELECT ... FOR UPDATE, but I don't know if all SQL DBs support it. Such a decorator would be important to make get_or_create() and a few other functions work 100% correctly, so it would also benefit the SQL layer. I couldn't provide the respective SQL implementations, though. Planned changes: Delegate deletion of related objects to background task. Maybe emulate multi-table inheritance with a ListField. Nonrel DBs need special handling for primary key fields. MongoDB and CouchDB store them in '_id' and App Engine uses a special property which is not part of the field values dictionary. In order to emulate JOINs we must store the column names of the primary keys used in the sql.Query instance. So, do you think this is a good path to take? Bye, Waldemar Kornewald -- http://twitter.com/wkornewald http://bitbucket.org/wkornewald/ http://allbuttonspressed.blogspot.com/
-- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
