backported django postgres backend fixes
This commit is contained in:
parent
20c72782ce
commit
7239b91a47
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dts_test_app', '0002_test_drop_unique'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='DummyModel',
|
||||||
|
name='indexed_value',
|
||||||
|
field=models.CharField(max_length=255, db_index=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,25 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dts_test_app', '0003_test_add_db_index'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='DummyModel',
|
||||||
|
name='indexed_value',
|
||||||
|
field=models.CharField(max_length=255, unique=True),
|
||||||
|
),
|
||||||
|
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='DummyModel',
|
||||||
|
name='indexed_value',
|
||||||
|
),
|
||||||
|
]
|
|
@ -5,6 +5,11 @@ from collections import namedtuple
|
||||||
from django.db.backends.base.introspection import (
|
from django.db.backends.base.introspection import (
|
||||||
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
BaseDatabaseIntrospection, FieldInfo, TableInfo,
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
# Django >= 1.11
|
||||||
|
from django.db.models.indexes import Index
|
||||||
|
except ImportError:
|
||||||
|
Index = None
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
fields = FieldInfo._fields
|
fields = FieldInfo._fields
|
||||||
|
@ -113,7 +118,8 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
FROM pg_attribute AS fka
|
FROM pg_attribute AS fka
|
||||||
JOIN pg_class AS fkc ON fka.attrelid = fkc.oid
|
JOIN pg_class AS fkc ON fka.attrelid = fkc.oid
|
||||||
WHERE fka.attrelid = c.confrelid
|
WHERE fka.attrelid = c.confrelid
|
||||||
AND fka.attnum = c.confkey[1])
|
AND fka.attnum = c.confkey[1]),
|
||||||
|
cl.reloptions
|
||||||
FROM pg_constraint AS c
|
FROM pg_constraint AS c
|
||||||
JOIN pg_class AS cl ON c.conrelid = cl.oid
|
JOIN pg_class AS cl ON c.conrelid = cl.oid
|
||||||
JOIN pg_namespace AS ns ON cl.relnamespace = ns.oid
|
JOIN pg_namespace AS ns ON cl.relnamespace = ns.oid
|
||||||
|
@ -135,35 +141,37 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
|
|
||||||
_get_index_constraints_query = """
|
_get_index_constraints_query = """
|
||||||
SELECT
|
SELECT
|
||||||
indexname, array_agg(attname), indisunique, indisprimary,
|
indexname, array_agg(attname ORDER BY rnum), indisunique, indisprimary,
|
||||||
array_agg(ordering), amname, exprdef
|
array_agg(ordering ORDER BY rnum), amname, exprdef, s2.attoptions
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
row_number() OVER () as rnum, c2.relname as indexname,
|
||||||
|
idx.*, attr.attname, am.amname,
|
||||||
|
CASE
|
||||||
|
WHEN idx.indexprs IS NOT NULL THEN
|
||||||
|
pg_get_indexdef(idx.indexrelid)
|
||||||
|
END AS exprdef,
|
||||||
|
CASE am.amname
|
||||||
|
WHEN 'btree' THEN
|
||||||
|
CASE (option & 1)
|
||||||
|
WHEN 1 THEN 'DESC' ELSE 'ASC'
|
||||||
|
END
|
||||||
|
END as ordering,
|
||||||
|
c2.reloptions as attoptions
|
||||||
FROM (
|
FROM (
|
||||||
SELECT
|
SELECT
|
||||||
c2.relname as indexname, idx.*, attr.attname, am.amname,
|
*, unnest(i.indkey) as key, unnest(i.indoption) as option
|
||||||
CASE
|
FROM pg_index i
|
||||||
WHEN idx.indexprs IS NOT NULL THEN
|
) idx
|
||||||
pg_get_indexdef(idx.indexrelid)
|
LEFT JOIN pg_class c ON idx.indrelid = c.oid
|
||||||
END AS exprdef,
|
LEFT JOIN pg_class c2 ON idx.indexrelid = c2.oid
|
||||||
CASE am.amname
|
LEFT JOIN pg_am am ON c2.relam = am.oid
|
||||||
WHEN 'btree' THEN
|
LEFT JOIN pg_attribute attr ON attr.attrelid = c.oid AND attr.attnum = idx.key
|
||||||
CASE (option & 1)
|
LEFT JOIN pg_namespace n ON c.relnamespace = n.oid
|
||||||
WHEN 1 THEN 'DESC' ELSE 'ASC'
|
WHERE c.relname = %(table)s
|
||||||
END
|
AND n.nspname = %(schema)s
|
||||||
END as ordering
|
) s2
|
||||||
FROM (
|
GROUP BY indexname, indisunique, indisprimary, amname, exprdef, attoptions;
|
||||||
SELECT
|
|
||||||
*, unnest(i.indkey) as key, unnest(i.indoption) as option
|
|
||||||
FROM pg_index i
|
|
||||||
) idx
|
|
||||||
LEFT JOIN pg_class c ON idx.indrelid = c.oid
|
|
||||||
LEFT JOIN pg_class c2 ON idx.indexrelid = c2.oid
|
|
||||||
LEFT JOIN pg_am am ON c2.relam = am.oid
|
|
||||||
LEFT JOIN pg_attribute attr ON attr.attrelid = c.oid AND attr.attnum = idx.key
|
|
||||||
LEFT JOIN pg_namespace n ON c.relnamespace = n.oid
|
|
||||||
WHERE c.relname = %(table)s
|
|
||||||
AND n.nspname = %(schema)s
|
|
||||||
) s2
|
|
||||||
GROUP BY indexname, indisunique, indisprimary, amname, exprdef;
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_field_type(self, data_type, description):
|
def get_field_type(self, data_type, description):
|
||||||
|
@ -274,7 +282,7 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
'table': table_name,
|
'table': table_name,
|
||||||
})
|
})
|
||||||
|
|
||||||
for constraint, columns, kind, used_cols in cursor.fetchall():
|
for constraint, columns, kind, used_cols, options in cursor.fetchall():
|
||||||
constraints[constraint] = {
|
constraints[constraint] = {
|
||||||
"columns": columns,
|
"columns": columns,
|
||||||
"primary_key": kind == "p",
|
"primary_key": kind == "p",
|
||||||
|
@ -283,6 +291,7 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
"check": kind == "c",
|
"check": kind == "c",
|
||||||
"index": False,
|
"index": False,
|
||||||
"definition": None,
|
"definition": None,
|
||||||
|
"options": options,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Now get indexes
|
# Now get indexes
|
||||||
|
@ -291,7 +300,7 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
'table': table_name,
|
'table': table_name,
|
||||||
})
|
})
|
||||||
|
|
||||||
for index, columns, unique, primary, orders, type_, definition in cursor.fetchall():
|
for index, columns, unique, primary, orders, type_, definition, options in cursor.fetchall():
|
||||||
if index not in constraints:
|
if index not in constraints:
|
||||||
constraints[index] = {
|
constraints[index] = {
|
||||||
"columns": columns if columns != [None] else [],
|
"columns": columns if columns != [None] else [],
|
||||||
|
@ -301,7 +310,8 @@ class DatabaseSchemaIntrospection(BaseDatabaseIntrospection):
|
||||||
"foreign_key": None,
|
"foreign_key": None,
|
||||||
"check": False,
|
"check": False,
|
||||||
"index": True,
|
"index": True,
|
||||||
"type": type_,
|
"type": Index.suffix if type_ == 'btree' and Index else type_,
|
||||||
"definition": definition,
|
"definition": definition,
|
||||||
|
"options": options,
|
||||||
}
|
}
|
||||||
return constraints
|
return constraints
|
||||||
|
|
Loading…
Reference in New Issue