Fixed #29350 -- Allowed SQLite pk introspection to work with formats besides double quotes.
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py
index bb78e2533efff..72e3d94955721 100644
--- a/django/db/backends/sqlite3/introspection.py
+++ b/django/db/backends/sqlite3/introspection.py
@@ -192,9 +192,9 @@ def get_primary_key_column(self, cursor, table_name):
         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 0000000000000..1695ee549e4cc
--- /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')

The `get_primary_key_column()` method in the `sqlite3` backend only expects a field with quotation. The solution is to make the capture group focus on the first word, regardless of whether or not it has quotation.

There are no existing test cases, so I've added those as well.

- Fix get_primary_key_column() method
- Add relevant models and test cases.