From 502d4982c9b5ce0a916145f7e78fb702afb8b60a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Sun, 19 Jul 2009 21:57:08 +0000 Subject: [PATCH] [soc2009/multidb] Raise an exception at an attempt to do a subquery with 2 different databases. Eventually we'll just evaluate the 2 queries seperates. git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11273 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- TODO.txt | 8 ++++---- django/db/models/fields/__init__.py | 4 ++-- django/db/models/fields/related.py | 4 ++-- django/db/models/query.py | 14 ++++++++++---- tests/regressiontests/multiple_database/tests.py | 2 ++ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/TODO.txt b/TODO.txt index eb47467dfb..b13387351f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -14,12 +14,12 @@ that need to be done. I'm trying to be as granular as possible. flush, reset, and syncdb need to not prompt the user multiple times. -3) Handle nesting of Querysets using __in across multiple dbs. +3) Handle backends with custom Query classes. -4) Handle backends with custom Query classes. +4) Wait on the merge of the m2m stuff. -5) Wait on the merge of the m2m stuff. +5) Fix django.contrib.gis, it's broken in all sorts of ways. -6) Fix django.contrib.gis, it's broken in all sorts of ways. +6) Generate SQL, instead of an error for nesting on different DBs. 7) Time permitting add support for a ``DatabaseManager``. diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index af2031ce10..8d327170cf 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -201,9 +201,9 @@ class Field(object): if hasattr(value, 'relabel_aliases'): return value if hasattr(value, 'as_sql'): - sql, params = value.as_sql() + sql, params = value.as_sql(connection) else: - sql, params = value._as_sql() + sql, params = value._as_sql(connection) return QueryWrapper(('(%s)' % sql), params) diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 33cef0bd17..5d43243912 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -149,9 +149,9 @@ class RelatedField(object): if hasattr(value, 'relabel_aliases'): return value if hasattr(value, 'as_sql'): - sql, params = value.as_sql() + sql, params = value.as_sql(connection) else: - sql, params = value._as_sql() + sql, params = value._as_sql(connection) return QueryWrapper(('(%s)' % sql), params) # FIXME: lt and gt are explicitally allowed to make diff --git a/django/db/models/query.py b/django/db/models/query.py index edfded0d03..8f4e435a12 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -745,12 +745,14 @@ class QuerySet(object): self.query.add_fields(field_names, False) self.query.set_group_by() - def _as_sql(self): + def _as_sql(self, connection): """ Returns the internal query's SQL and parameters (as a tuple). """ obj = self.values("pk") - return obj.query.as_nested_sql() + if connection.settings_dict == obj.query.connection.settings_dict: + return obj.query.as_nested_sql() + raise ValueError("Can't do subqueries with queries on different DBs.") def _validate(self): """ @@ -863,7 +865,7 @@ class ValuesQuerySet(QuerySet): super(ValuesQuerySet, self)._setup_aggregate_query(aggregates) - def _as_sql(self): + def _as_sql(self, connection): """ For ValueQuerySet (and subclasses like ValuesListQuerySet), they can only be used as nested queries if they're already set up to select only @@ -875,7 +877,11 @@ class ValuesQuerySet(QuerySet): (not self._fields and len(self.model._meta.fields) > 1)): raise TypeError('Cannot use a multi-field %s as a filter value.' % self.__class__.__name__) - return self._clone().query.as_nested_sql() + + obj = self._clone() + if connection.settings_dict == obj.query.connection.settings_dict: + return obj.query.as_nested_sql() + raise ValueError("Can't do subqueries with queries on different DBs.") def _validate(self): """ diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py index de312c5c14..6c98291330 100644 --- a/tests/regressiontests/multiple_database/tests.py +++ b/tests/regressiontests/multiple_database/tests.py @@ -93,3 +93,5 @@ if len(settings.DATABASES) > 1: a.delete() self.assertRaises(Article.DoesNotExist, lambda: Article.objects.get(title="Django Rules!")) + self.assertRaises(ValueError, + lambda: list(Article.objects.get(pk__in=Article.objects.using('default'))))