From: Mike Bayer Date: Wed, 19 Sep 2012 04:34:30 +0000 (-0400) Subject: - [bug] Adjusted a very old bugfix which attempted X-Git-Tag: rel_0_7_9~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da626917a8e9d5514717de07893c713c0de85b7d;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - [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] --- diff --git a/CHANGES b/CHANGES index 1aac9a7110..ed87284e30 100644 --- 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, diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 793d0c49b3..1c6f0d88ab 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -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 , 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 b76ac3ed85..a4c9b4e7c7 100644 --- a/test/dialect/test_sqlite.py +++ b/test/dialect/test_sqlite.py @@ -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()