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 datetime
import warnings
from django.conf import settings from django.conf import settings
from django.core.exceptions import FieldError 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.transaction import TransactionManagementError
from django.db.utils import DatabaseError from django.db.utils import DatabaseError
from django.utils import six from django.utils import six
from django.utils.six.moves import zip
from django.utils import timezone from django.utils import timezone
from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.six.moves import zip
class SQLCompiler(object): class SQLCompiler(object):
@ -46,6 +48,17 @@ class SQLCompiler(object):
self.fill_related_selections() self.fill_related_selections()
def __call__(self, name): 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 A wrapper around connection.ops.quote_name that doesn't quote aliases
for table names. This avoids problems with some SQL dialects that treat for table names. This avoids problems with some SQL dialects that treat
@ -61,14 +74,6 @@ class SQLCompiler(object):
self.quote_cache[name] = r self.quote_cache[name] = r
return 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): def compile(self, node):
vendor_impl = getattr( vendor_impl = getattr(
node, 'as_' + self.connection.vendor, None) 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 (without the table names) are given unique aliases. This is needed in
some cases to avoid ambiguity with nested queries. some cases to avoid ambiguity with nested queries.
""" """
qn = self qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)] result = ['(%s) AS %s' % (col[0], qn2(alias)) for alias, col in six.iteritems(self.query.extra_select)]
params = [] params = []
@ -285,7 +290,7 @@ class SQLCompiler(object):
result = [] result = []
if opts is None: if opts is None:
opts = self.query.get_meta() opts = self.query.get_meta()
qn = self qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
aliases = set() aliases = set()
only_load = self.deferred_to_columns() 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 Note that this method can alter the tables in the query, and thus it
must be called before get_from_clause(). must be called before get_from_clause().
""" """
qn = self qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
result = [] result = []
opts = self.query.get_meta() opts = self.query.get_meta()
@ -370,7 +375,7 @@ class SQLCompiler(object):
ordering = (self.query.order_by ordering = (self.query.order_by
or self.query.get_meta().ordering or self.query.get_meta().ordering
or []) or [])
qn = self qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
distinct = self.query.distinct distinct = self.query.distinct
select_aliases = self._select_aliases select_aliases = self._select_aliases
@ -509,7 +514,7 @@ class SQLCompiler(object):
ordering and distinct must be done first. ordering and distinct must be done first.
""" """
result = [] result = []
qn = self qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
first = True first = True
from_params = [] from_params = []
@ -559,7 +564,7 @@ class SQLCompiler(object):
""" """
Returns a tuple representing the SQL elements in the "group by" clause. Returns a tuple representing the SQL elements in the "group by" clause.
""" """
qn = self qn = self.quote_name_unless_alias
result, params = [], [] result, params = [], []
if self.query.group_by is not None: if self.query.group_by is not None:
select_cols = self.query.select + self.query.related_select_cols select_cols = self.query.select + self.query.related_select_cols
@ -853,8 +858,9 @@ class SQLCompiler(object):
cursor.close() cursor.close()
return result return result
def as_subquery_condition(self, alias, columns, qn): def as_subquery_condition(self, alias, columns, compiler):
inner_qn = self qn = compiler.quote_name_unless_alias
inner_qn = self.quote_name_unless_alias
qn2 = self.connection.ops.quote_name qn2 = self.connection.ops.quote_name
if len(columns) == 1: if len(columns) == 1:
sql, params = self.as_sql() sql, params = self.as_sql()
@ -967,7 +973,7 @@ class SQLDeleteCompiler(SQLCompiler):
""" """
assert len(self.query.tables) == 1, \ assert len(self.query.tables) == 1, \
"Can only delete from one table at a time." "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])] result = ['DELETE FROM %s' % qn(self.query.tables[0])]
where, params = self.compile(self.query.where) where, params = self.compile(self.query.where)
if where: if where:
@ -985,7 +991,7 @@ class SQLUpdateCompiler(SQLCompiler):
if not self.query.values: if not self.query.values:
return '', () return '', ()
table = self.query.tables[0] table = self.query.tables[0]
qn = self qn = self.quote_name_unless_alias
result = ['UPDATE %s' % qn(table)] result = ['UPDATE %s' % qn(table)]
result.append('SET') result.append('SET')
values, update_params = [], [] 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 See the :ref:`Django 1.8 release notes<deprecated-features-1.8>` for more
details on these changes. 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`` * ``cycle`` and ``firstof`` template tags will be removed from the ``future``
template tag library (used during the 1.6/1.7 deprecation period). 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 Private API ``django.test.utils.TestTemplateLoader`` is deprecated in favor of
``django.template.loaders.locmem.Loader``. ``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: .. removed-features-1.8:
Features removed in 1.8 Features removed in 1.8