Loading django/db/backends/sqlite3/introspection.py +8 −1 Original line number Diff line number Diff line Loading @@ -106,16 +106,23 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): # Walk through and look for references to other tables. SQLite doesn't # really have enforced references, but since it echoes out the SQL used # to create the table we can look for REFERENCES statements used there. field_names = [] for field_index, field_desc in enumerate(results.split(',')): field_desc = field_desc.strip() if field_desc.startswith("UNIQUE"): continue m = re.search('references (.*) \(["|](.*)["|]\)', field_desc, re.I) field_names.append(field_desc.split()[0].strip('"')) m = re.search('references (\S*) ?\(["|]?(.*)["|]?\)', field_desc, re.I) if not m: continue table, column = [s.strip('"') for s in m.groups()] if field_desc.startswith("FOREIGN KEY"): # Find index of the target FK field m = re.match('FOREIGN KEY\(([^\)]*)\).*', field_desc, re.I) fkey_field = m.groups()[0].strip('"') field_index = field_names.index(fkey_field) cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s", [table]) result = cursor.fetchall()[0] Loading tests/introspection/tests.py +13 −1 Original line number Diff line number Diff line from __future__ import unicode_literals from unittest import skipUnless from django.db import connection from django.db.utils import DatabaseError from django.test import TransactionTestCase, skipUnlessDBFeature from django.test import TransactionTestCase, mock, skipUnlessDBFeature from .models import Reporter, Article Loading Loading @@ -119,6 +121,16 @@ class IntrospectionTests(TransactionTestCase): self.assertEqual(relations, {3: (0, Reporter._meta.db_table), 4: (0, Article._meta.db_table)}) @skipUnless(connection.vendor == 'sqlite', "This is an sqlite-specific issue") def test_get_relations_alt_format(self): """With SQLite, foreign keys can be added with different syntaxes.""" with connection.cursor() as cursor: cursor.fetchone = mock.Mock(return_value=[ "CREATE TABLE track(id, art INTEGER, FOREIGN KEY(art) REFERENCES %s(id));" % Article._meta.db_table ]) relations = connection.introspection.get_relations(cursor, 'mocked_table') self.assertEqual(relations, {1: (0, Article._meta.db_table)}) @skipUnlessDBFeature('can_introspect_foreign_keys') def test_get_key_columns(self): with connection.cursor() as cursor: Loading Loading
django/db/backends/sqlite3/introspection.py +8 −1 Original line number Diff line number Diff line Loading @@ -106,16 +106,23 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): # Walk through and look for references to other tables. SQLite doesn't # really have enforced references, but since it echoes out the SQL used # to create the table we can look for REFERENCES statements used there. field_names = [] for field_index, field_desc in enumerate(results.split(',')): field_desc = field_desc.strip() if field_desc.startswith("UNIQUE"): continue m = re.search('references (.*) \(["|](.*)["|]\)', field_desc, re.I) field_names.append(field_desc.split()[0].strip('"')) m = re.search('references (\S*) ?\(["|]?(.*)["|]?\)', field_desc, re.I) if not m: continue table, column = [s.strip('"') for s in m.groups()] if field_desc.startswith("FOREIGN KEY"): # Find index of the target FK field m = re.match('FOREIGN KEY\(([^\)]*)\).*', field_desc, re.I) fkey_field = m.groups()[0].strip('"') field_index = field_names.index(fkey_field) cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s", [table]) result = cursor.fetchall()[0] Loading
tests/introspection/tests.py +13 −1 Original line number Diff line number Diff line from __future__ import unicode_literals from unittest import skipUnless from django.db import connection from django.db.utils import DatabaseError from django.test import TransactionTestCase, skipUnlessDBFeature from django.test import TransactionTestCase, mock, skipUnlessDBFeature from .models import Reporter, Article Loading Loading @@ -119,6 +121,16 @@ class IntrospectionTests(TransactionTestCase): self.assertEqual(relations, {3: (0, Reporter._meta.db_table), 4: (0, Article._meta.db_table)}) @skipUnless(connection.vendor == 'sqlite', "This is an sqlite-specific issue") def test_get_relations_alt_format(self): """With SQLite, foreign keys can be added with different syntaxes.""" with connection.cursor() as cursor: cursor.fetchone = mock.Mock(return_value=[ "CREATE TABLE track(id, art INTEGER, FOREIGN KEY(art) REFERENCES %s(id));" % Article._meta.db_table ]) relations = connection.introspection.get_relations(cursor, 'mocked_table') self.assertEqual(relations, {1: (0, Article._meta.db_table)}) @skipUnlessDBFeature('can_introspect_foreign_keys') def test_get_key_columns(self): with connection.cursor() as cursor: Loading