Skip to content

Commit c683b04

Browse files
committed
finish inspectdb
1 parent 68a3df8 commit c683b04

File tree

1 file changed

+88
-9
lines changed

1 file changed

+88
-9
lines changed

django_iris/introspection.py

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
from django.db.models import Index
77
from django.utils.datastructures import OrderedSet
88

9-
FieldInfo = namedtuple('FieldInfo', BaseFieldInfo._fields + ('auto_increment', ))
9+
FieldInfo = namedtuple(
10+
'FieldInfo', BaseFieldInfo._fields + ('auto_increment', ))
11+
1012

1113
class DatabaseIntrospection(BaseDatabaseIntrospection):
1214
data_types_reverse = {
@@ -100,8 +102,18 @@ def get_relations(self, cursor, table_name):
100102
representing all relationships to the given table.
101103
"""
102104
# Dictionary of relations to return
103-
relations = {}
104-
return relations
105+
cursor.execute("""
106+
SELECT column_name, referenced_column_name, referenced_table_name
107+
FROM information_schema.key_column_usage
108+
WHERE table_schema = %s
109+
AND table_name = %s
110+
AND referenced_table_name IS NOT NULL
111+
AND referenced_column_name IS NOT NULL
112+
""", ['SQLUser', table_name])
113+
return {
114+
field_name: (other_field, other_table)
115+
for field_name, other_field, other_table in cursor.fetchall()
116+
}
105117

106118
# def get_primary_key_column(self, cursor, table_name):
107119
# """
@@ -129,8 +141,73 @@ def get_constraints(self, cursor, table_name):
129141
if they don't name constraints of a certain type (e.g. SQLite)
130142
"""
131143
constraints = {}
144+
# Get the actual constraint names and columns
145+
name_query = """
146+
SELECT kc.constraint_name, kc.column_name,
147+
kc.referenced_table_name, kc.referenced_column_name,
148+
c.constraint_type
149+
FROM
150+
information_schema.key_column_usage AS kc,
151+
information_schema.table_constraints AS c
152+
WHERE
153+
kc.table_schema = %s AND
154+
c.table_schema = kc.table_schema AND
155+
c.constraint_name = kc.constraint_name AND
156+
c.constraint_type != 'CHECK' AND
157+
kc.table_name = %s
158+
ORDER BY kc.ordinal_position
159+
"""
160+
cursor.execute(name_query, ['SQLUser', table_name])
161+
for constraint, column, ref_table, ref_column, kind in cursor.fetchall():
162+
if constraint not in constraints:
163+
constraints[constraint] = {
164+
'columns': OrderedSet(),
165+
'primary_key': kind == 'PRIMARY KEY',
166+
'unique': kind in {'PRIMARY KEY', 'UNIQUE'},
167+
'index': False,
168+
'check': False,
169+
'foreign_key': (ref_table, ref_column) if ref_column else None,
170+
}
171+
if self.connection.features.supports_index_column_ordering:
172+
constraints[constraint]['orders'] = []
173+
constraints[constraint]['columns'].add(column)
174+
# Add check constraints.
175+
if self.connection.features.can_introspect_check_constraints:
176+
unnamed_constraints_index = 0
177+
columns = {info.name for info in self.get_table_description(
178+
cursor, table_name)}
179+
type_query = """
180+
SELECT cc.constraint_name, cc.check_clause
181+
FROM
182+
information_schema.check_constraints AS cc,
183+
information_schema.table_constraints AS tc
184+
WHERE
185+
cc.constraint_schema = %s AND
186+
tc.table_schema = cc.constraint_schema AND
187+
cc.constraint_name = tc.constraint_name AND
188+
tc.constraint_type = 'CHECK' AND
189+
tc.table_name = %s
190+
"""
191+
cursor.execute(type_query, ['SQLUser', table_name])
192+
for constraint, check_clause in cursor.fetchall():
193+
constraint_columns = self._parse_constraint_columns(
194+
check_clause, columns)
195+
# Ensure uniqueness of unnamed constraints. Unnamed unique
196+
# and check columns constraints have the same name as
197+
# a column.
198+
if set(constraint_columns) == {constraint}:
199+
unnamed_constraints_index += 1
200+
constraint = '__unnamed_constraint_%s__' % unnamed_constraints_index
201+
constraints[constraint] = {
202+
'columns': constraint_columns,
203+
'primary_key': False,
204+
'unique': False,
205+
'index': False,
206+
'check': True,
207+
'foreign_key': None,
208+
}
132209

133-
cursor.execute("""
210+
index_query = """
134211
SELECT
135212
INDEX_NAME,
136213
COLUMN_NAME,
@@ -141,21 +218,23 @@ def get_constraints(self, cursor, table_name):
141218
WHERE TABLE_SCHEMA = %s
142219
AND TABLE_NAME = %s
143220
ORDER BY ORDINAL_POSITION
144-
""",
145-
['SQLUser', table_name]
146-
)
221+
"""
222+
cursor.execute(index_query, ['SQLUser', table_name])
147223
for index, column, primary, non_unique, order in cursor.fetchall():
148224
if index not in constraints:
149225
constraints[index] = {
150-
'columns': [],
226+
'columns': OrderedSet(),
151227
'primary_key': primary == 1,
152228
'unique': not non_unique,
153229
'check': False,
154230
'foreign_key': None,
155231
'orders': [],
156232
}
157-
constraints[index]['columns'].append(column)
233+
constraints[index]['columns'].add(column)
158234
constraints[index]['orders'].append(
159235
'DESC' if order == 'D' else 'ASC')
160236

237+
# Convert the sorted sets to lists
238+
for constraint in constraints.values():
239+
constraint['columns'] = list(constraint['columns'])
161240
return constraints

0 commit comments

Comments
 (0)