From: Mike Bayer Date: Wed, 16 Nov 2016 14:57:36 +0000 (-0500) Subject: Port lower case quoted name fix to firebird X-Git-Tag: rel_1_1_5~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68d3018ceefc33e42135ee208d6d492a47e695c7;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Port lower case quoted name fix to firebird Ported the fix for Oracle quoted-lowercase names to Firebird, so that a table name that is quoted as lower case can be reflected properly including when the table name comes from the get_table_names() inspection function. Also genericize the test to the test suite for denormlized name dialects. Fixes: #3548 Change-Id: I8ca62e8d2b359e363ccb01cfe2daa0995354a3cb --- diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index 879ba79a4d..f6334203d7 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -21,6 +21,15 @@ .. changelog:: :version: 1.1.5 + .. change:: 3548 + :tag: bug, firebird + :tickets: 3548 + + Ported the fix for Oracle quoted-lowercase names to Firebird, so that + a table name that is quoted as lower case can be reflected properly + including when the table name comes from the get_table_names() + inspection function. + .. changelog:: :version: 1.1.4 :released: November 15, 2016 diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index 16e2c55b83..e552fae4b1 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -77,6 +77,7 @@ from sqlalchemy import exc, types as sqltypes, sql, util from sqlalchemy.sql import expression from sqlalchemy.engine import base, default, reflection from sqlalchemy.sql import compiler +from sqlalchemy.sql.elements import quoted_name from sqlalchemy.types import (BIGINT, BLOB, DATE, FLOAT, INTEGER, NUMERIC, SMALLINT, TEXT, TIME, TIMESTAMP, Integer) @@ -439,6 +440,8 @@ class FBDialect(default.DefaultDialect): elif name.upper() == name and \ not self.identifier_preparer._requires_quotes(name.lower()): return name.lower() + elif name.lower() == name: + return quoted_name(name, quote=True) else: return name diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py index 090d5b0678..ed6a33b6d4 100644 --- a/lib/sqlalchemy/testing/suite/test_reflection.py +++ b/lib/sqlalchemy/testing/suite/test_reflection.py @@ -14,6 +14,8 @@ from .. import config import operator from sqlalchemy.schema import DDL, Index from sqlalchemy import event +from sqlalchemy.sql.elements import quoted_name +from sqlalchemy import ForeignKey metadata, users = None, None @@ -705,4 +707,40 @@ class ComponentReflectionTest(fixtures.TablesTest): assert id_.get('autoincrement', True) -__all__ = ('ComponentReflectionTest', 'HasTableTest') +class NormalizedNameTest(fixtures.TablesTest): + __requires__ = 'denormalized_names', + __backend__ = True + + @classmethod + def define_tables(cls, metadata): + Table( + quoted_name('t1', quote=True), metadata, + Column('id', Integer, primary_key=True), + ) + Table( + quoted_name('t2', quote=True), metadata, + Column('id', Integer, primary_key=True), + Column('t1id', ForeignKey('t1.id')) + ) + + def test_reflect_lowercase_forced_tables(self): + + m2 = MetaData(testing.db) + t2_ref = Table(quoted_name('t2', quote=True), m2, autoload=True) + t1_ref = m2.tables['t1'] + assert t2_ref.c.t1id.references(t1_ref.c.id) + + m3 = MetaData(testing.db) + m3.reflect(only=lambda name, m: name.lower() in ('t1', 't2')) + assert m3.tables['t2'].c.t1id.references(m3.tables['t1'].c.id) + + def test_get_table_names(self): + tablenames = [ + t for t in inspect(testing.db).get_table_names() + if t.lower() in ("t1", "t2")] + + eq_(tablenames[0].upper(), tablenames[0].lower()) + eq_(tablenames[1].upper(), tablenames[1].lower()) + + +__all__ = ('ComponentReflectionTest', 'HasTableTest', 'NormalizedNameTest') diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py index 82cc107fda..79d37237c9 100644 --- a/test/dialect/test_oracle.py +++ b/test/dialect/test_oracle.py @@ -2008,29 +2008,6 @@ class TableReflectionTest(fixtures.TestBase): tbl = Table('test_compress', m2, autoload=True) assert tbl.dialect_options['oracle']['compress'] == "OLTP" - @testing.provide_metadata - def test_reflect_lowercase_forced_tables(self): - metadata = self.metadata - - Table( - quoted_name('t1', quote=True), metadata, - Column('id', Integer, primary_key=True), - ) - Table( - quoted_name('t2', quote=True), metadata, - Column('id', Integer, primary_key=True), - Column('t1id', ForeignKey('t1.id')) - ) - metadata.create_all() - - m2 = MetaData(testing.db) - t2_ref = Table(quoted_name('t2', quote=True), m2, autoload=True) - t1_ref = m2.tables['t1'] - assert t2_ref.c.t1id.references(t1_ref.c.id) - - m3 = MetaData(testing.db) - m3.reflect(only=lambda name, m: name.lower() in ('t1', 't2')) - assert m3.tables['t2'].c.t1id.references(m3.tables['t1'].c.id)