diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-04-04 12:02:51 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-04-04 12:02:51 -0400 |
commit | ecd7b31d5eaed138e699293719f70260da3c978d (patch) | |
tree | 9290647481a09b18e37a438428e68f379191baa8 | |
parent | ee40c7afaabe33e2080607de0045a9fd0a4748d8 (diff) | |
download | sqlalchemy-ecd7b31d5eaed138e699293719f70260da3c978d.tar.gz |
- Fixed a long-standing bug where the :class:`.Enum` type as used
with the psycopg2 dialect in conjunction with non-ascii values
and ``native_enum=False`` would fail to decode return results properly.
This stemmed from when the PG :class:`.postgresql.ENUM` type used
to be a standalone type without a "non native" option.
fixes #3354
- corrected the assertsql comparison rule to expect a non-ascii
SQL string
-rw-r--r-- | doc/build/changelog/changelog_09.rst | 10 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/psycopg2.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/assertsql.py | 2 | ||||
-rw-r--r-- | test/dialect/postgresql/test_types.py | 60 |
4 files changed, 62 insertions, 12 deletions
diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index ab1292f49..382af7680 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -15,6 +15,16 @@ :version: 0.9.10 .. change:: + :tags: bug, postgresql + :tickets: 3354 + + Fixed a long-standing bug where the :class:`.Enum` type as used + with the psycopg2 dialect in conjunction with non-ascii values + and ``native_enum=False`` would fail to decode return results properly. + This stemmed from when the PG :class:`.postgresql.ENUM` type used + to be a standalone type without a "non native" option. + + .. change:: :tags: bug, orm :tickets: 3349 diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 46228ac15..f66ba9693 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -354,7 +354,7 @@ class _PGNumeric(sqltypes.Numeric): class _PGEnum(ENUM): def result_processor(self, dialect, coltype): - if util.py2k and self.convert_unicode is True: + if self.native_enum and util.py2k and self.convert_unicode is True: # we can't easily use PG's extensions here because # the OID is on the fly, and we need to give it a python # function anyway - not really worth it. diff --git a/lib/sqlalchemy/testing/assertsql.py b/lib/sqlalchemy/testing/assertsql.py index a596d9743..e544adad2 100644 --- a/lib/sqlalchemy/testing/assertsql.py +++ b/lib/sqlalchemy/testing/assertsql.py @@ -85,7 +85,7 @@ class CompiledSQL(SQLMatchRule): column_keys=context.compiled.column_keys, inline=context.compiled.inline) ) - _received_statement = re.sub(r'[\n\t]', '', str(compiled)) + _received_statement = re.sub(r'[\n\t]', '', util.text_type(compiled)) parameters = execute_observed.parameters if not parameters: diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index 393ef43de..e26526ef3 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -171,8 +171,9 @@ class EnumTest(fixtures.TestBase, AssertsExecutionResults): (util.u('réveillé'), util.u('drôle'), util.u('S’il')) ) - def test_non_native_type(self): - metadata = MetaData() + @testing.provide_metadata + def test_non_native_enum(self): + metadata = self.metadata t1 = Table( 'foo', metadata, @@ -188,14 +189,53 @@ class EnumTest(fixtures.TestBase, AssertsExecutionResults): def go(): t1.create(testing.db) - try: - self.assert_sql( - testing.db, go, [ - ("CREATE TABLE foo (\tbar " - "VARCHAR(5), \tCONSTRAINT myenum CHECK " - "(bar IN ('one', 'two', 'three')))", {})]) - finally: - metadata.drop_all(testing.db) + self.assert_sql( + testing.db, go, [ + ("CREATE TABLE foo (\tbar " + "VARCHAR(5), \tCONSTRAINT myenum CHECK " + "(bar IN ('one', 'two', 'three')))", {})]) + with testing.db.begin() as conn: + conn.execute( + t1.insert(), {'bar': 'two'} + ) + eq_( + conn.scalar(select([t1.c.bar])), 'two' + ) + + @testing.provide_metadata + def test_non_native_enum_w_unicode(self): + metadata = self.metadata + t1 = Table( + 'foo', + metadata, + Column( + 'bar', + Enum('B', util.u('Ü'), name='myenum', native_enum=False))) + + def go(): + t1.create(testing.db) + + self.assert_sql( + testing.db, + go, + [ + ( + util.u( + "CREATE TABLE foo (\tbar " + "VARCHAR(1), \tCONSTRAINT myenum CHECK " + "(bar IN ('B', 'Ü')))" + ), + {} + ) + ]) + + with testing.db.begin() as conn: + conn.execute( + t1.insert(), {'bar': util.u('Ü')} + ) + eq_( + conn.scalar(select([t1.c.bar])), util.u('Ü') + ) @testing.provide_metadata def test_disable_create(self): |