Skip to content

Commit

Permalink
- Fixed a long-standing bug where the :class:.Enum type as used
Browse files Browse the repository at this point in the history
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
  • Loading branch information
zzzeek committed Apr 4, 2015
1 parent ee40c7a commit ecd7b31
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
10 changes: 10 additions & 0 deletions doc/build/changelog/changelog_09.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
.. changelog::
: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
Expand Down
2 changes: 1 addition & 1 deletion lib/sqlalchemy/dialects/postgresql/psycopg2.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def result_processor(self, dialect, coltype):

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.
Expand Down
2 changes: 1 addition & 1 deletion lib/sqlalchemy/testing/assertsql.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _received_statement(self, execute_observed):
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:
Expand Down
60 changes: 50 additions & 10 deletions test/dialect/postgresql/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ def test_unicode_labels(self):
(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,
Expand All @@ -188,14 +189,53 @@ def test_non_native_type(self):
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):
Expand Down

0 comments on commit ecd7b31

Please sign in to comment.