]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed a long-standing bug where the :class:`.Enum` type as used
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 4 Apr 2015 16:02:51 +0000 (12:02 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 4 Apr 2015 16:02:51 +0000 (12:02 -0400)
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

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/dialects/postgresql/psycopg2.py
lib/sqlalchemy/testing/assertsql.py
test/dialect/postgresql/test_types.py

index ab1292f494f3b8d646e7fa335466b1f9587ba431..382af7680b53f6b788f33ebc059133219ceeaa45 100644 (file)
 .. 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
index 46228ac158588b10b677fed5a0311799a66c8c4d..f66ba9693b46454f07d905c7765eff77d697764f 100644 (file)
@@ -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.
index a596d97437fd3bf4658d2dbbedeaa0015ac2817e..e544adad26069093644efcf8e502f0deb68b13b0 100644 (file)
@@ -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:
index 393ef43dea79eb1243813a5ed4ed407760ec89b9..e26526ef3e3ea003badf0e679e9f7de5a24e0a8d 100644 (file)
@@ -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):