]> 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:07:34 +0000 (12:07 -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
cherry pick from ecd7b31d5eaed138e699293719f70260da3c978d

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/dialects/postgresql/psycopg2.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 e8904734db4215b87ab7642769f4aaa69cbff4e4..0c95f74c1cf0036048585158b9f71dffe2c8b803 100644 (file)
@@ -341,7 +341,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 098bb7e047c230c914b8d585966d53d67ba0abab..079a1fcaded98c4a34d45c5eda1c1c6bdf4ef46b 100644 (file)
@@ -170,8 +170,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,
@@ -187,14 +188,53 @@ class EnumTest(fixtures.TestBase, AssertsExecutionResults):
         def go():
             t1.create(testing.db)
 
-        try:
-            self.assert_sql(
-                testing.db, go, [], with_sequences=[
-                    ("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):