This commit is contained in:
parent
3fe92f4477
commit
4c7bf83cde
|
@ -24,16 +24,14 @@ class PostGISIntrospection(DatabaseIntrospection):
|
|||
# expression over the raster column through the ST_ConvexHull function.
|
||||
# So the default query has to be adapted to include raster indices.
|
||||
_get_indexes_query = """
|
||||
SELECT DISTINCT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary,
|
||||
am.amname
|
||||
SELECT DISTINCT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
|
||||
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index idx,
|
||||
pg_catalog.pg_attribute attr, pg_catalog.pg_type t, pg_catalog.pg_am am
|
||||
pg_catalog.pg_attribute attr, pg_catalog.pg_type t
|
||||
WHERE
|
||||
c.oid = idx.indrelid
|
||||
AND idx.indexrelid = c2.oid
|
||||
AND attr.attrelid = c.oid
|
||||
AND t.oid = attr.atttypid
|
||||
AND c2.relam = am.oid
|
||||
AND (
|
||||
attr.attnum = idx.indkey[0] OR
|
||||
(t.typname LIKE 'raster' AND idx.indkey = '0')
|
||||
|
|
|
@ -36,15 +36,13 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
ignored_tables = []
|
||||
|
||||
_get_indexes_query = """
|
||||
SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary,
|
||||
am.amname
|
||||
SELECT attr.attname, idx.indkey, idx.indisunique, idx.indisprimary
|
||||
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2,
|
||||
pg_catalog.pg_index idx, pg_catalog.pg_attribute attr, pg_catalog.pg_am am
|
||||
pg_catalog.pg_index idx, pg_catalog.pg_attribute attr
|
||||
WHERE c.oid = idx.indrelid
|
||||
AND idx.indexrelid = c2.oid
|
||||
AND attr.attrelid = c.oid
|
||||
AND attr.attnum = idx.indkey[0]
|
||||
AND c2.relam = am.oid
|
||||
AND c.relname = %s"""
|
||||
|
||||
def get_field_type(self, data_type, description):
|
||||
|
@ -134,7 +132,6 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
# row[1] (idx.indkey) is stored in the DB as an array. It comes out as
|
||||
# a string of space-separated integers. This designates the field
|
||||
# indexes (1-based) of the fields that have indexes on the table.
|
||||
# row[4] is the type of index, e.g. btree, hash, etc.
|
||||
# Here, we skip any indexes across multiple fields.
|
||||
if ' ' in row[1]:
|
||||
continue
|
||||
|
@ -145,7 +142,6 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
indexes[row[0]]['primary_key'] = True
|
||||
if row[2]:
|
||||
indexes[row[0]]['unique'] = True
|
||||
indexes[row[0]]['type'] = row[4]
|
||||
return indexes
|
||||
|
||||
def get_constraints(self, cursor, table_name):
|
||||
|
@ -216,10 +212,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
cursor.execute("""
|
||||
SELECT
|
||||
indexname, array_agg(attname), indisunique, indisprimary,
|
||||
array_agg(ordering)
|
||||
array_agg(ordering), amname
|
||||
FROM (
|
||||
SELECT
|
||||
c2.relname as indexname, idx.*, attr.attname,
|
||||
c2.relname as indexname, idx.*, attr.attname, am.amname,
|
||||
CASE
|
||||
WHEN am.amcanorder THEN
|
||||
CASE (option & 1)
|
||||
|
@ -238,9 +234,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
AND c2.relam=am.oid
|
||||
AND c.relname = %s
|
||||
) s2
|
||||
GROUP BY indexname, indisunique, indisprimary;
|
||||
GROUP BY indexname, indisunique, indisprimary, amname;;
|
||||
""", [table_name])
|
||||
for index, columns, unique, primary, orders in cursor.fetchall():
|
||||
for index, columns, unique, primary, orders, type_ in cursor.fetchall():
|
||||
if index not in constraints:
|
||||
constraints[index] = {
|
||||
"columns": columns,
|
||||
|
@ -250,5 +246,6 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
"foreign_key": None,
|
||||
"check": False,
|
||||
"index": True,
|
||||
"type": type_,
|
||||
}
|
||||
return constraints
|
||||
|
|
|
@ -172,11 +172,6 @@ class IntrospectionTests(TransactionTestCase):
|
|||
def test_get_indexes(self):
|
||||
with connection.cursor() as cursor:
|
||||
indexes = connection.introspection.get_indexes(cursor, Article._meta.db_table)
|
||||
if connection.features.can_introspect_index_type:
|
||||
index_type = indexes['reporter_id'].pop('type', None)
|
||||
self.assertIsNotNone(index_type)
|
||||
if connection.vendor == 'postgresql':
|
||||
self.assertEqual(index_type, 'btree')
|
||||
self.assertEqual(indexes['reporter_id'], {'unique': False, 'primary_key': False})
|
||||
|
||||
def test_get_indexes_multicol(self):
|
||||
|
@ -189,6 +184,14 @@ class IntrospectionTests(TransactionTestCase):
|
|||
self.assertNotIn('first_name', indexes)
|
||||
self.assertIn('id', indexes)
|
||||
|
||||
@skipUnlessDBFeature('can_introspect_index_type')
|
||||
def test_get_constraints_index_types(self):
|
||||
with connection.cursor() as cursor:
|
||||
constraints = connection.introspection.get_constraints(cursor, Article._meta.db_table)
|
||||
for key, val in constraints.items():
|
||||
if val['index'] and not (val['primary_key'] or val['unique']):
|
||||
self.assertEqual(val['type'], 'btree')
|
||||
|
||||
@skipUnlessDBFeature('supports_index_column_ordering')
|
||||
def test_get_constraints_indexes_orders(self):
|
||||
"""
|
||||
|
|
|
@ -33,23 +33,24 @@ class GinIndexTests(PostgreSQLTestCase):
|
|||
|
||||
class SchemaTests(PostgreSQLTestCase):
|
||||
|
||||
def get_indexes(self, table):
|
||||
def get_constraints(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 connection.introspection.get_constraints(cursor, table)
|
||||
|
||||
def test_gin_index(self):
|
||||
# Ensure the table is there and doesn't have an index.
|
||||
self.assertNotIn('field', self.get_indexes(IntegerArrayModel._meta.db_table))
|
||||
self.assertNotIn('field', self.get_constraints(IntegerArrayModel._meta.db_table))
|
||||
# Add the index
|
||||
index = GinIndex(fields=['field'], name='integer_array_model_field_gin')
|
||||
with connection.schema_editor() as editor:
|
||||
editor.add_index(IntegerArrayModel, index)
|
||||
self.assertIn('field', self.get_indexes(IntegerArrayModel._meta.db_table))
|
||||
self.assertEqual(self.get_indexes(IntegerArrayModel._meta.db_table)['field']['type'], 'gin')
|
||||
self.assertIn('integer_array_model_field_gin', self.get_constraints(IntegerArrayModel._meta.db_table))
|
||||
constraints = self.get_constraints(IntegerArrayModel._meta.db_table)
|
||||
self.assertEqual(constraints['integer_array_model_field_gin']['type'], 'gin')
|
||||
# Drop the index
|
||||
with connection.schema_editor() as editor:
|
||||
editor.remove_index(IntegerArrayModel, index)
|
||||
self.assertNotIn('field', self.get_indexes(IntegerArrayModel._meta.db_table))
|
||||
self.assertNotIn('integer_array_model_field_gin', self.get_constraints(IntegerArrayModel._meta.db_table))
|
||||
|
|
Loading…
Reference in New Issue