diff options
-rw-r--r-- | CHANGES | 14 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 10 | ||||
-rw-r--r-- | test/dialect/test_sqlite.py | 57 |
3 files changed, 64 insertions, 17 deletions
@@ -824,6 +824,20 @@ are also present in 0.8. 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, diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 717d6b49a..651fa05e5 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -723,7 +723,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) @@ -780,9 +779,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: diff --git a/test/dialect/test_sqlite.py b/test/dialect/test_sqlite.py index 4ce3d8fb6..cfc49af12 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -385,11 +385,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 @@ -405,16 +405,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() |