]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] Adjusted a very old bugfix which attempted
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 19 Sep 2012 04:34:30 +0000 (00:34 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 19 Sep 2012 04:34:30 +0000 (00:34 -0400)
    to work around a SQLite issue that itself was
    "fixed" as of sqlite 3.6.14, regarding quotes
    surrounding a table name when using
    the "foreign_key_list" pragma.  The fix has been
    adjusted to not interfere with quotes that
    are *actually in the name* of a column or table,
    to as much a degree as possible; sqlite still
    doesn't return the correct result for foreign_key_list()
    if the target table actually has quotes surrounding
    its name, as *part* of its name (i.e. """mytable""").
    [ticket:2568]

CHANGES
lib/sqlalchemy/dialects/sqlite/base.py
test/dialect/test_sqlite.py

diff --git a/CHANGES b/CHANGES
index 1aac9a7110513ed9b0150a4638de6341200831ee..ed87284e305a3ab9cb188983bd1be0b1fab80770 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -126,6 +126,20 @@ CHANGES
     the "name" and "native_enum" flags.  Helps
     Alembic autogenerate.
 
+- sqlite
+  - [bug] Adjusted a very old bugfix which attempted
+    to work around a SQLite issue that itself was
+    "fixed" as of sqlite 3.6.14, regarding quotes
+    surrounding a table name when using
+    the "foreign_key_list" pragma.  The fix has been
+    adjusted to not interfere with quotes that
+    are *actually in the name* of a column or table,
+    to as much a degree as possible; sqlite still
+    doesn't return the correct result for foreign_key_list()
+    if the target table actually has quotes surrounding
+    its name, as *part* of its name (i.e. """mytable""").
+    [ticket:2568]
+
 - mysql
   - [bug] Updated mysqlconnector interface to use
     updated "client flag" and "charset" APIs,
index 793d0c49b36e85eb4dc912603c6bc10b4d4890d8..1c6f0d88ab36356e227f61d919ab0459673cc5f4 100644 (file)
@@ -681,7 +681,6 @@ class SQLiteDialect(default.DefaultDialect):
             (name, type_, nullable, default, has_default, primary_key) = \
                 (row[1], row[2].upper(), not row[3],
                 row[4], row[4] is not None, row[5])
-            name = re.sub(r'^\"|\"$', '', name)
             match = re.match(r'(\w+)(\(.*?\))?', type_)
             if match:
                 coltype = match.group(1)
@@ -738,9 +737,12 @@ class SQLiteDialect(default.DefaultDialect):
             # was created with REFERENCES <tablename>, no col
             if rcol is None:
                 rcol = lcol
-            rtbl = re.sub(r'^\"|\"$', '', rtbl)
-            lcol = re.sub(r'^\"|\"$', '', lcol)
-            rcol = re.sub(r'^\"|\"$', '', rcol)
+
+            # see http://www.sqlalchemy.org/trac/ticket/2568
+            # as well as http://www.sqlite.org/src/info/600482d161
+            if self.dbapi.sqlite_version_info < (3, 6, 14):
+                rtbl = re.sub(r'^\"|\"$', '', rtbl)
+
             try:
                 fk = fks[numerical_id]
             except KeyError:
index b76ac3ed85b5b4c6eab073e260898abb6a49700e..a4c9b4e7c786d8f600b6cab2a75cec6d613eb4d4 100644 (file)
@@ -300,11 +300,11 @@ class DialectTest(fixtures.TestBase, AssertsExecutionResults):
         finally:
             meta.drop_all()
 
-    def test_quoted_identifiers(self):
+    @testing.provide_metadata
+    def test_quoted_identifiers_one(self):
         """Tests autoload of tables created with quoted column names."""
 
-        # This is quirky in sqlite.
-
+        metadata = self.metadata
         testing.db.execute("""CREATE TABLE "django_content_type" (
             "id" integer NOT NULL PRIMARY KEY,
             "django_stuff" text NULL
@@ -320,16 +320,47 @@ class DialectTest(fixtures.TestBase, AssertsExecutionResults):
             "change_message" text NOT NULL
         )
         """)
-        try:
-            meta = MetaData(testing.db)
-            table1 = Table('django_admin_log', meta, autoload=True)
-            table2 = Table('django_content_type', meta, autoload=True)
-            j = table1.join(table2)
-            assert j.onclause.compare(table1.c.content_type_id
-                    == table2.c.id)
-        finally:
-            testing.db.execute('drop table django_admin_log')
-            testing.db.execute('drop table django_content_type')
+        table1 = Table('django_admin_log', metadata, autoload=True)
+        table2 = Table('django_content_type', metadata, autoload=True)
+        j = table1.join(table2)
+        assert j.onclause.compare(table1.c.content_type_id
+                == table2.c.id)
+
+    @testing.provide_metadata
+    def test_quoted_identifiers_two(self):
+        """"test the edgiest of edge cases, quoted table/col names
+        that start and end with quotes.
+
+        SQLite claims to have fixed this in
+        http://www.sqlite.org/src/info/600482d161, however
+        it still fails if the FK points to a table name that actually
+        has quotes as part of its name.
+
+        """
+
+        metadata = self.metadata
+        testing.db.execute(r'''CREATE TABLE """a""" (
+            """id""" integer NOT NULL PRIMARY KEY
+        )
+        ''')
+
+        # unfortunately, still can't do this; sqlite quadruples
+        # up the quotes on the table name here for pragma foreign_key_list
+        #testing.db.execute(r'''
+        #CREATE TABLE """b""" (
+        #    """id""" integer NOT NULL PRIMARY KEY,
+        #    """aid""" integer NULL
+        #           REFERENCES """a""" ("""id""")
+        #)
+        #''')
+
+        table1 = Table(r'"a"', metadata, autoload=True)
+        assert '"id"' in table1.c
+
+        #table2 = Table(r'"b"', metadata, autoload=True)
+        #j = table1.join(table2)
+        #assert j.onclause.compare(table1.c['"id"']
+        #        == table2.c['"aid"'])
 
     def test_attached_as_schema(self):
         cx = testing.db.connect()