summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2015-04-04 12:02:51 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2015-04-04 12:02:51 -0400
commitecd7b31d5eaed138e699293719f70260da3c978d (patch)
tree9290647481a09b18e37a438428e68f379191baa8
parentee40c7afaabe33e2080607de0045a9fd0a4748d8 (diff)
downloadsqlalchemy-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.rst10
-rw-r--r--lib/sqlalchemy/dialects/postgresql/psycopg2.py2
-rw-r--r--lib/sqlalchemy/testing/assertsql.py2
-rw-r--r--test/dialect/postgresql/test_types.py60
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):