From 60197fb0f4adc738a5f73a85d9c996b1259ea9e1 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 20 Oct 2010 17:28:08 -0400 Subject: [PATCH] - Fixed bug which prevented "domain" built from a custom type such as "enum" from being reflected. [ticket:1933] --- CHANGES | 4 +++ lib/sqlalchemy/dialects/postgresql/base.py | 36 ++++++++++++---------- test/dialect/test_postgresql.py | 23 ++++++++++++-- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 04c75ac596..c2ebff1c49 100644 --- a/CHANGES +++ b/CHANGES @@ -197,6 +197,10 @@ CHANGES - postgresql - Added "as_tuple" flag to ARRAY type, returns results as tuples instead of lists to allow hashing. + + - Fixed bug which prevented "domain" built from a + custom type such as "enum" from being reflected. + [ticket:1933] - mssql - Fixed reflection bug which did not properly handle diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 03260cdb34..0d103cb0dc 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1053,28 +1053,32 @@ class PGDialect(default.DefaultDialect): else: args = () - if attype in self.ischema_names: - coltype = self.ischema_names[attype] - elif attype in enums: - enum = enums[attype] - coltype = ENUM - if "." in attype: - kwargs['schema'], kwargs['name'] = attype.split('.') - else: - kwargs['name'] = attype - args = tuple(enum['labels']) - elif attype in domains: - domain = domains[attype] - if domain['attype'] in self.ischema_names: + while True: + if attype in self.ischema_names: + coltype = self.ischema_names[attype] + break + elif attype in enums: + enum = enums[attype] + coltype = ENUM + if "." in attype: + kwargs['schema'], kwargs['name'] = attype.split('.') + else: + kwargs['name'] = attype + args = tuple(enum['labels']) + break + elif attype in domains: + domain = domains[attype] + attype = domain['attype'] # A table can't override whether the domain is nullable. nullable = domain['nullable'] if domain['default'] and not default: # It can, however, override the default # value, but can't set it to null. default = domain['default'] - coltype = self.ischema_names[domain['attype']] - else: - coltype = None + continue + else: + coltype = None + break if coltype: coltype = coltype(*args, **kwargs) diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index 36aa7f2c6f..e20274aefa 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -909,7 +909,10 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults): con = testing.db.connect() for ddl in \ 'CREATE DOMAIN testdomain INTEGER NOT NULL DEFAULT 42', \ - 'CREATE DOMAIN test_schema.testdomain INTEGER DEFAULT 0': + 'CREATE DOMAIN test_schema.testdomain INTEGER DEFAULT 0', \ + "CREATE TYPE testtype AS ENUM ('test')", \ + 'CREATE DOMAIN enumdomain AS testtype'\ + : try: con.execute(ddl) except exc.SQLError, e: @@ -923,6 +926,8 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults): con.execute('CREATE TABLE crosschema (question integer, answer ' 'test_schema.testdomain)') + con.execute('CREATE TABLE enum_test (id integer, data enumdomain)') + @classmethod def teardown_class(cls): con = testing.db.connect() @@ -931,7 +936,10 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults): con.execute('DROP TABLE crosschema') con.execute('DROP DOMAIN testdomain') con.execute('DROP DOMAIN test_schema.testdomain') - + con.execute("DROP TABLE enum_test") + con.execute("DROP DOMAIN enumdomain") + con.execute("DROP TYPE testtype") + def test_table_is_reflected(self): metadata = MetaData(testing.db) table = Table('testtable', metadata, autoload=True) @@ -946,7 +954,15 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults): "Reflected default value didn't equal expected value") assert not table.columns.answer.nullable, \ 'Expected reflected column to not be nullable.' - + + def test_enum_domain_is_reflected(self): + metadata = MetaData(testing.db) + table = Table('enum_test', metadata, autoload=True) + eq_( + table.c.data.type.enums, + ('test', ) + ) + def test_table_is_reflected_test_schema(self): metadata = MetaData(testing.db) table = Table('testtable', metadata, autoload=True, @@ -990,6 +1006,7 @@ class DomainReflectionTest(TestBase, AssertsExecutionResults): finally: postgresql.PGDialect.ischema_names = ischema_names + class MiscTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL): __only_on__ = 'postgresql' -- 2.47.2