diff options
-rw-r--r-- | doc/build/changelog/changelog_08.rst | 12 | ||||
-rw-r--r-- | lib/sqlalchemy/dialects/mssql/pyodbc.py | 3 | ||||
-rw-r--r-- | test/sql/test_unicode.py | 22 |
3 files changed, 36 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 01590b090..15f38fc45 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -12,6 +12,18 @@ :version: 0.8.7 .. change:: + :tags: bug, mssql + :versions: 1.0.0, 0.9.7 + :tickets: 3091 + + In the SQL Server pyodbc dialect, repaired the implementation + for the ``description_encoding`` dialect parameter, which when + not explicitly set was preventing cursor.description from + being parsed correctly in the case of result sets that + contained names in alternate encodings. This parameter + shouldn't be needed going forward. + + .. change:: :tags: bug, sql :versions: 1.0.0, 0.9.7 :tickets: 3124 diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py index ab45fa25e..31c55f502 100644 --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py @@ -250,8 +250,9 @@ class MSDialect_pyodbc(PyODBCConnector, MSDialect): ) def __init__(self, description_encoding=None, **params): + if 'description_encoding' in params: + self.description_encoding = params.pop('description_encoding') super(MSDialect_pyodbc, self).__init__(**params) - self.description_encoding = description_encoding self.use_scope_identity = self.use_scope_identity and \ self.dbapi and \ hasattr(self.dbapi.Cursor, 'nextset') diff --git a/test/sql/test_unicode.py b/test/sql/test_unicode.py index 99de16f7f..fc5205a3d 100644 --- a/test/sql/test_unicode.py +++ b/test/sql/test_unicode.py @@ -79,6 +79,28 @@ class UnicodeSchemaTest(fixtures.TestBase): assert t2.select().execute().fetchall() == [(1, 1)] assert t3.select().execute().fetchall() == [(1, 5, 1, 1)] + def test_col_targeting(self): + t1.insert().execute({u('méil'): 1, ue('\u6e2c\u8a66'): 5}) + t2.insert().execute({u('a'): 1, u('b'): 1}) + t3.insert().execute({ue('\u6e2c\u8a66_id'): 1, + ue('unitable1_\u6e2c\u8a66'): 5, + u('Unitéble2_b'): 1, + ue('\u6e2c\u8a66_self'): 1}) + + row = t1.select().execute().first() + eq_(row[t1.c[u('méil')]], 1) + eq_(row[t1.c[ue('\u6e2c\u8a66')]], 5) + + row = t2.select().execute().first() + eq_(row[t2.c[u('a')]], 1) + eq_(row[t2.c[u('b')]], 1) + + row = t3.select().execute().first() + eq_(row[t3.c[ue('\u6e2c\u8a66_id')]], 1) + eq_(row[t3.c[ue('unitable1_\u6e2c\u8a66')]], 5) + eq_(row[t3.c[u('Unitéble2_b')]], 1) + eq_(row[t3.c[ue('\u6e2c\u8a66_self')]], 1) + def test_reflect(self): t1.insert().execute({u('méil'): 2, ue('\u6e2c\u8a66'): 7}) t2.insert().execute({u('a'): 2, u('b'): 2}) |