Fixed #27098 -- Deprecated DatabaseIntrospection.get_indexes
Thanks Akshesh <aksheshdoshi@gmail.com> for help with the PostgreSQL query. Thanks Tim Graham for the review.
This commit is contained in:
parent
1ec1633cb2
commit
d389125606
|
@ -61,11 +61,18 @@ class SpatiaLiteIntrospection(DatabaseIntrospection):
|
|||
|
||||
return field_type, field_params
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
indexes = super(SpatiaLiteIntrospection, self).get_indexes(cursor, table_name)
|
||||
def get_constraints(self, cursor, table_name):
|
||||
constraints = super(SpatiaLiteIntrospection, self).get_constraints(cursor, table_name)
|
||||
cursor.execute('SELECT f_geometry_column '
|
||||
'FROM geometry_columns '
|
||||
'WHERE f_table_name=%s AND spatial_index_enabled=1', (table_name,))
|
||||
for row in cursor.fetchall():
|
||||
indexes[row[0]] = {'primary_key': False, 'unique': False}
|
||||
return indexes
|
||||
constraints['%s__spatial__index' % row[0]] = {
|
||||
"columns": [row[0]],
|
||||
"primary_key": False,
|
||||
"unique": False,
|
||||
"foreign_key": None,
|
||||
"check": False,
|
||||
"index": True,
|
||||
}
|
||||
return constraints
|
||||
|
|
|
@ -70,14 +70,15 @@ class Command(BaseCommand):
|
|||
relations = connection.introspection.get_relations(cursor, table_name)
|
||||
except NotImplementedError:
|
||||
relations = {}
|
||||
try:
|
||||
indexes = connection.introspection.get_indexes(cursor, table_name)
|
||||
except NotImplementedError:
|
||||
indexes = {}
|
||||
try:
|
||||
constraints = connection.introspection.get_constraints(cursor, table_name)
|
||||
except NotImplementedError:
|
||||
constraints = {}
|
||||
primary_key_column = connection.introspection.get_primary_key_column(cursor, table_name)
|
||||
unique_columns = [
|
||||
c['columns'][0] for c in constraints.values()
|
||||
if c['unique'] and len(c['columns']) == 1
|
||||
]
|
||||
table_description = connection.introspection.get_table_description(cursor, table_name)
|
||||
except Exception as e:
|
||||
yield "# Unable to inspect table '%s'" % table_name
|
||||
|
@ -105,11 +106,10 @@ class Command(BaseCommand):
|
|||
column_to_field_name[column_name] = att_name
|
||||
|
||||
# Add primary_key and unique, if necessary.
|
||||
if column_name in indexes:
|
||||
if indexes[column_name]['primary_key']:
|
||||
extra_params['primary_key'] = True
|
||||
elif indexes[column_name]['unique']:
|
||||
extra_params['unique'] = True
|
||||
if column_name == primary_key_column:
|
||||
extra_params['primary_key'] = True
|
||||
elif column_name in unique_columns:
|
||||
extra_params['unique'] = True
|
||||
|
||||
if is_relation:
|
||||
rel_to = (
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
from collections import namedtuple
|
||||
|
||||
from django.utils import six
|
||||
|
||||
# Structure returned by DatabaseIntrospection.get_table_list()
|
||||
TableInfo = namedtuple('TableInfo', ['name', 'type'])
|
||||
|
||||
|
@ -143,13 +141,14 @@ class BaseDatabaseIntrospection(object):
|
|||
"""
|
||||
Returns the name of the primary key column for the given table.
|
||||
"""
|
||||
for column in six.iteritems(self.get_indexes(cursor, table_name)):
|
||||
if column[1]['primary_key']:
|
||||
return column[0]
|
||||
for constraint in self.get_constraints(cursor, table_name).values():
|
||||
if constraint['primary_key']:
|
||||
return constraint['columns'][0]
|
||||
return None
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
"""
|
||||
Deprecated in Django 1.11, use get_constraints instead.
|
||||
Returns a dictionary of indexed fieldname -> infodict for the given
|
||||
table, where each infodict is in the format:
|
||||
{'primary_key': boolean representing whether it's the primary key,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import warnings
|
||||
from collections import namedtuple
|
||||
|
||||
from MySQLdb.constants import FIELD_TYPE
|
||||
|
@ -6,6 +7,7 @@ from django.db.backends.base.introspection import (
|
|||
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
||||
)
|
||||
from django.utils.datastructures import OrderedSet
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra', 'default'))
|
||||
|
@ -122,6 +124,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
return key_columns
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
warnings.warn(
|
||||
"get_indexes() is deprecated in favor of get_constraints().",
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(table_name))
|
||||
# Do a two-pass search for indexes: on first pass check which indexes
|
||||
# are multicolumn, on second pass check which single-column indexes
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import warnings
|
||||
|
||||
import cx_Oracle
|
||||
|
||||
from django.db.backends.base.introspection import (
|
||||
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
||||
)
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
|
||||
|
@ -117,6 +120,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
for row in cursor.fetchall()]
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
warnings.warn(
|
||||
"get_indexes() is deprecated in favor of get_constraints().",
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
sql = """
|
||||
SELECT LOWER(uic1.column_name) AS column_name,
|
||||
CASE user_constraints.constraint_type
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
|
||||
from django.db.backends.base.introspection import (
|
||||
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
||||
)
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('default',))
|
||||
|
@ -124,6 +126,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
return key_columns
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
warnings.warn(
|
||||
"get_indexes() is deprecated in favor of get_constraints().",
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
# This query retrieves each index on the given table, including the
|
||||
# first associated field name
|
||||
cursor.execute(self._get_indexes_query, [table_name])
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import re
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
|
||||
from django.db.backends.base.introspection import (
|
||||
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
||||
)
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
|
||||
field_size_re = re.compile(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$')
|
||||
FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('default',))
|
||||
|
@ -183,6 +185,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
return key_columns
|
||||
|
||||
def get_indexes(self, cursor, table_name):
|
||||
warnings.warn(
|
||||
"get_indexes() is deprecated in favor of get_constraints().",
|
||||
RemovedInDjango21Warning, stacklevel=2
|
||||
)
|
||||
indexes = {}
|
||||
for info in self._table_info(cursor, table_name):
|
||||
if info['pk'] != 0:
|
||||
|
|
|
@ -36,6 +36,8 @@ details on these changes.
|
|||
* Silencing of exceptions raised while rendering the ``{% include %}`` template
|
||||
tag will be removed.
|
||||
|
||||
* ``DatabaseIntrospection.get_indexes()`` will be removed.
|
||||
|
||||
.. _deprecation-removed-in-2.0:
|
||||
|
||||
2.0
|
||||
|
|
|
@ -399,6 +399,10 @@ Database backend API
|
|||
dictionaries with a list of ``'ASC'`` and/or ``'DESC'`` values corresponding
|
||||
to the the ordering of each column in the index.
|
||||
|
||||
* :djadmin:`inspectdb` no longer calls ``DatabaseIntrospection.get_indexes()``
|
||||
which is deprecated. Custom database backends should ensure all types of
|
||||
indexes are returned by ``DatabaseIntrospection.get_constraints()``.
|
||||
|
||||
Dropped support for PostgreSQL 9.2 and PostGIS 2.0
|
||||
--------------------------------------------------
|
||||
|
||||
|
@ -549,3 +553,6 @@ Miscellaneous
|
|||
:ttag:`{% include %} <include>` template tag is deprecated as the behavior is
|
||||
often more confusing than helpful. In Django 2.1, the exception will be
|
||||
raised.
|
||||
|
||||
* ``DatabaseIntrospection.get_indexes()`` is deprecated in favor of
|
||||
``DatabaseIntrospection.get_constraints()``.
|
||||
|
|
|
@ -69,8 +69,8 @@ class OperationTests(TransactionTestCase):
|
|||
|
||||
def assertSpatialIndexExists(self, table, column):
|
||||
with connection.cursor() as cursor:
|
||||
indexes = connection.introspection.get_indexes(cursor, table)
|
||||
self.assertIn(column, indexes)
|
||||
constraints = connection.introspection.get_constraints(cursor, table)
|
||||
self.assertIn([column], [c['columns'] for c in constraints.values()])
|
||||
|
||||
def alter_gis_model(self, migration_class, model_name, field_name,
|
||||
blank=False, field_class=None):
|
||||
|
|
|
@ -5,6 +5,8 @@ from unittest import skipUnless
|
|||
from django.db import connection
|
||||
from django.db.utils import DatabaseError
|
||||
from django.test import TransactionTestCase, mock, skipUnlessDBFeature
|
||||
from django.test.utils import ignore_warnings
|
||||
from django.utils.deprecation import RemovedInDjango21Warning
|
||||
|
||||
from .models import Article, ArticleReporter, City, District, Reporter
|
||||
|
||||
|
@ -169,11 +171,13 @@ class IntrospectionTests(TransactionTestCase):
|
|||
self.assertEqual(primary_key_column, 'id')
|
||||
self.assertEqual(pk_fk_column, 'city_id')
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_get_indexes(self):
|
||||
with connection.cursor() as cursor:
|
||||
indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table)
|
||||
self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False})
|
||||
|
||||
@ignore_warnings(category=RemovedInDjango21Warning)
|
||||
def test_get_indexes_multicol(self):
|
||||
"""
|
||||
Test that multicolumn indexes are not included in the introspection
|
||||
|
|
|
@ -483,9 +483,13 @@ class TestMigrations(TransactionTestCase):
|
|||
]
|
||||
# Only the CharField should have a LIKE index.
|
||||
self.assertEqual(like_constraint_columns_list, [['char2']])
|
||||
with connection.cursor() as cursor:
|
||||
indexes = connection.introspection.get_indexes(cursor, table_name)
|
||||
# All fields should have regular indexes.
|
||||
with connection.cursor() as cursor:
|
||||
indexes = [
|
||||
c['columns'][0]
|
||||
for c in connection.introspection.get_constraints(cursor, table_name).values()
|
||||
if c['index'] and len(c['columns']) == 1
|
||||
]
|
||||
self.assertIn('char', indexes)
|
||||
self.assertIn('char2', indexes)
|
||||
self.assertIn('text', indexes)
|
||||
|
|
|
@ -105,12 +105,20 @@ class SchemaTests(TransactionTestCase):
|
|||
raise DatabaseError("Table does not exist (empty pragma)")
|
||||
return columns
|
||||
|
||||
def get_primary_key(self, table):
|
||||
with connection.cursor() as cursor:
|
||||
return connection.introspection.get_primary_key_column(cursor, table)
|
||||
|
||||
def get_indexes(self, table):
|
||||
"""
|
||||
Get the indexes on the table using a new cursor.
|
||||
"""
|
||||
with connection.cursor() as cursor:
|
||||
return connection.introspection.get_indexes(cursor, table)
|
||||
return [
|
||||
c['columns'][0]
|
||||
for c in connection.introspection.get_constraints(cursor, table).values()
|
||||
if c['index'] and len(c['columns']) == 1
|
||||
]
|
||||
|
||||
def get_constraints(self, table):
|
||||
"""
|
||||
|
@ -1685,9 +1693,7 @@ class SchemaTests(TransactionTestCase):
|
|||
with connection.schema_editor() as editor:
|
||||
editor.create_model(Tag)
|
||||
# Ensure the table is there and has the right PK
|
||||
self.assertTrue(
|
||||
self.get_indexes(Tag._meta.db_table)['id']['primary_key'],
|
||||
)
|
||||
self.assertEqual(self.get_primary_key(Tag._meta.db_table), 'id')
|
||||
# Alter to change the PK
|
||||
id_field = Tag._meta.get_field("id")
|
||||
old_field = Tag._meta.get_field("slug")
|
||||
|
@ -1702,9 +1708,7 @@ class SchemaTests(TransactionTestCase):
|
|||
'id',
|
||||
self.get_indexes(Tag._meta.db_table),
|
||||
)
|
||||
self.assertTrue(
|
||||
self.get_indexes(Tag._meta.db_table)['slug']['primary_key'],
|
||||
)
|
||||
self.assertEqual(self.get_primary_key(Tag._meta.db_table), 'slug')
|
||||
|
||||
def test_context_manager_exit(self):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue