From 30f8642f2e9f4ed64ddb09163e09c1ca073b935a Mon Sep 17 00:00:00 2001 From: Zackary Troop Date: Sat, 28 Apr 2018 06:01:45 -0400 Subject: [PATCH] Fixed #29350 -- Fix get_primary_key_column() method in sqlite3 backend Thanks Tim Graham and Mariusz Felisiak for the reviews. --- django/db/backends/sqlite3/introspection.py | 4 +-- tests/backends/sqlite/test_introspection.py | 27 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/backends/sqlite/test_introspection.py diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index bb78e2533ef..72e3d949557 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -192,9 +192,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): fields_sql = create_sql[create_sql.index('(') + 1:create_sql.rindex(')')] for field_desc in fields_sql.split(','): field_desc = field_desc.strip() - m = re.search('"(.*)".*PRIMARY KEY( AUTOINCREMENT)?', field_desc) + m = re.match('(?:(?:["`\[])(.*)(?:["`\]])|(\w+)).*PRIMARY KEY.*', field_desc) if m: - return m.groups()[0] + return m.group(1) if m.group(1) else m.group(2) return None def _table_info(self, cursor, name): diff --git a/tests/backends/sqlite/test_introspection.py b/tests/backends/sqlite/test_introspection.py new file mode 100644 index 00000000000..1695ee549e4 --- /dev/null +++ b/tests/backends/sqlite/test_introspection.py @@ -0,0 +1,27 @@ +import unittest + +from django.db import connection +from django.test import TestCase + + +@unittest.skipUnless(connection.vendor == 'sqlite', 'SQLite tests') +class IntrospectionTests(TestCase): + def test_get_primary_key_column(self): + """ + Get the primary key column regardless of whether or not it has + quotation. + """ + testable_column_strings = ( + ('id', 'id'), ('[id]', 'id'), ('`id`', 'id'), ('"id"', 'id'), + ('[id col]', 'id col'), ('`id col`', 'id col'), ('"id col"', 'id col') + ) + with connection.cursor() as cursor: + for column, expected_string in testable_column_strings: + sql = 'CREATE TABLE test_primary (%s int PRIMARY KEY NOT NULL)' % column + with self.subTest(column=column): + try: + cursor.execute(sql) + field = connection.introspection.get_primary_key_column(cursor, 'test_primary') + self.assertEqual(field, expected_string) + finally: + cursor.execute('DROP TABLE test_primary')