Deprecated calling a SQLCompiler instance.

This commit is contained in:
Carl Meyer 2014-11-17 18:05:14 -07:00
parent d63703f1cd
commit 08fbbaa45b
3 changed files with 42 additions and 19 deletions

View File

@ -1,4 +1,5 @@
import datetime
import warnings
from django.conf import settings
from django.core.exceptions import FieldError
@ -12,8 +13,9 @@ from django.db.models.sql.query import get_order_dir, Query
from django.db.transaction import TransactionManagementError
from django.db.utils import DatabaseError
from django.utils import six
from django.utils.six.moves import zip
from django.utils import timezone
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.six.moves import zip
class SQLCompiler(object):
@ -46,6 +48,17 @@ class SQLCompiler(object):
self.fill_related_selections()
def __call__(self, name):
"""
Backwards-compatibility shim so that calling a SQLCompiler is equivalent to
calling its quote_name_unless_alias method.
"""
warnings.warn(
"Calling a SQLCompiler directly is deprecated. "
"Call compiler.quote_name_unless_alias instead.",
RemovedInDjango20Warning, stacklevel=2)
return self.quote_name_unless_alias(name)
def quote_name_unless_alias(self, name):
"""
A wrapper around connection.ops.quote_name that doesn't quote aliases
for table names. This avoids problems with some SQL dialects that treat
@ -61,14 +74,6 @@ class SQLCompiler(object):
self.quote_cache[name] = r
return r
def quote_name_unless_alias(self, name):
"""
A wrapper around connection.ops.quote_name that doesn't quote aliases
for table names. This avoids problems with some SQL dialects that treat
quoted strings specially (e.g. PostgreSQL).
"""
return self(name)
def compile(self, node):
vendor_impl = getattr(
node, 'as_' + self.connection.vendor, None)
@ -198,7 +203,7 @@ class SQLCompiler(object):
(without the table names) are given unique aliases. This is needed in
some cases to avoid ambiguity with nested queries.
"""
qn = self
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)]
params = []
@ -285,7 +290,7 @@ class SQLCompiler(object):
result = []
if opts is None:
opts = self.query.get_meta()
qn = self
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
aliases = set()
only_load = self.deferred_to_columns()
@ -337,7 +342,7 @@ class SQLCompiler(object):
Note that this method can alter the tables in the query, and thus it
must be called before get_from_clause().
"""
qn = self
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
result = []
opts = self.query.get_meta()
@ -370,7 +375,7 @@ class SQLCompiler(object):
ordering = (self.query.order_by
or self.query.get_meta().ordering
or [])
qn = self
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
distinct = self.query.distinct
select_aliases = self._select_aliases
@ -509,7 +514,7 @@ class SQLCompiler(object):
ordering and distinct must be done first.
"""
result = []
qn = self
qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
first = True
from_params = []
@ -559,7 +564,7 @@ class SQLCompiler(object):
"""
Returns a tuple representing the SQL elements in the "group by" clause.
"""
qn = self
qn = self.quote_name_unless_alias
result, params = [], []
if self.query.group_by is not None:
select_cols = self.query.select + self.query.related_select_cols
@ -853,8 +858,9 @@ class SQLCompiler(object):
cursor.close()
return result
def as_subquery_condition(self, alias, columns, qn):
inner_qn = self
def as_subquery_condition(self, alias, columns, compiler):
qn = compiler.quote_name_unless_alias
inner_qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name
if len(columns) == 1:
sql, params = self.as_sql()
@ -967,7 +973,7 @@ class SQLDeleteCompiler(SQLCompiler):
"""
assert len(self.query.tables) == 1, \
"Can only delete from one table at a time."
qn = self
qn = self.quote_name_unless_alias
result = ['DELETE FROM %s' % qn(self.query.tables[0])]
where, params = self.compile(self.query.where)
if where:
@ -985,7 +991,7 @@ class SQLUpdateCompiler(SQLCompiler):
if not self.query.values:
return '', ()
table = self.query.tables[0]
qn = self
qn = self.quote_name_unless_alias
result = ['UPDATE %s' % qn(table)]
result.append('SET')
values, update_params = [], []

View File

@ -15,6 +15,9 @@ about each item can often be found in the release notes of two versions prior.
See the :ref:`Django 1.8 release notes<deprecated-features-1.8>` for more
details on these changes.
* Support for calling a ``SQLCompiler`` directly as an alias for calling its
``quote_name_unless_alias`` method will be removed.
* ``cycle`` and ``firstof`` template tags will be removed from the ``future``
template tag library (used during the 1.6/1.7 deprecation period).

View File

@ -1049,6 +1049,20 @@ loader that inherits ``BaseLoader``, you must inherit ``Loader`` instead.
Private API ``django.test.utils.TestTemplateLoader`` is deprecated in favor of
``django.template.loaders.locmem.Loader``.
``qn`` replaced by ``compiler``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In previous Django versions, various internal ORM methods (mostly ``as_sql``
methods) accepted a ``qn`` (for "quote name") argument, which was a reference
to a function that quoted identifiers for sending to the database. In Django
1.8, that argument has been renamed to ``compiler`` and is now a full
``SQLCompiler`` instance. For backwards-compatibility, calling a
``SQLCompiler`` instance performs the same name-quoting that the ``qn``
function used to. However, this backwards-compatibility shim is immediately
deprecated: you should rename your ``qn`` arguments to ``compiler``, and call
``compiler.quote_name_unless_alias(...)`` where you previously called
``qn(...)``.
.. removed-features-1.8:
Features removed in 1.8