From: Mike Bayer Date: Thu, 21 Nov 2013 18:30:32 +0000 (-0500) Subject: - Fixed bug which prevented the ``serializer`` extension from working X-Git-Tag: rel_0_8_4~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3a3aeb431e08277346078fe60437f1fcfde957e2;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Fixed bug which prevented the ``serializer`` extension from working correctly with table or column names that contain non-ASCII characters. [ticket:2869] Conflicts: lib/sqlalchemy/ext/serializer.py lib/sqlalchemy/sql/selectable.py lib/sqlalchemy/testing/assertions.py --- diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 3a5844bbb4..dde98e82f5 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -11,6 +11,15 @@ .. changelog:: :version: 0.8.4 + .. change:: + :tags: bug, ext + :tickets: 2869 + :versions: 0.9.0b2 + + Fixed bug which prevented the ``serializer`` extension from working + correctly with table or column names that contain non-ASCII + characters. + .. change:: :tags: bug, orm :tickets: 2818 diff --git a/lib/sqlalchemy/ext/serializer.py b/lib/sqlalchemy/ext/serializer.py index 5a3fb59370..12820e07e5 100644 --- a/lib/sqlalchemy/ext/serializer.py +++ b/lib/sqlalchemy/ext/serializer.py @@ -58,7 +58,7 @@ from ..orm.interfaces import MapperProperty from ..orm.attributes import QueryableAttribute from .. import Table, Column from ..engine import Engine -from ..util import pickle +from ..util import pickle, text_type import re import base64 # Py3K @@ -95,9 +95,9 @@ def Serializer(*args, **kw): id = "mapperprop:" + b64encode(pickle.dumps(obj.parent.class_)) + \ ":" + obj.key elif isinstance(obj, Table): - id = "table:" + str(obj) + id = "table:" + text_type(obj.key) elif isinstance(obj, Column) and isinstance(obj.table, Table): - id = "column:" + str(obj.table) + ":" + obj.key + id = "column:" + text_type(obj.table.key) + ":" + text_type(obj.key) elif isinstance(obj, Session): id = "session:" elif isinstance(obj, Engine): @@ -127,7 +127,7 @@ def Deserializer(file, metadata=None, scoped_session=None, engine=None): return None def persistent_load(id): - m = our_ids.match(str(id)) + m = our_ids.match(text_type(id)) if not m: return None else: diff --git a/lib/sqlalchemy/testing/assertions.py b/lib/sqlalchemy/testing/assertions.py index ebd10b1308..d8b54dd353 100644 --- a/lib/sqlalchemy/testing/assertions.py +++ b/lib/sqlalchemy/testing/assertions.py @@ -205,12 +205,13 @@ class AssertsCompiledSQL(object): c = clause.compile(dialect=dialect, **kw) param_str = repr(getattr(c, 'params', {})) - # Py3K - #param_str = param_str.encode('utf-8').decode('ascii', 'ignore') - print "\nSQL String:\n" + str(c) + param_str + if util.py3k: + param_str = param_str.encode('utf-8').decode('ascii', 'ignore') - cc = re.sub(r'[\n\t]', '', str(c)) + print("\nSQL String:\n" + util.text_type(c).encode('utf-8') + param_str) + + cc = re.sub(r'[\n\t]', '', util.text_type(c)) eq_(cc, result, "%r != %r on dialect %r" % (cc, result, dialect)) diff --git a/test/ext/test_serializer.py b/test/ext/test_serializer.py index 402b64fe2b..e16453148a 100644 --- a/test/ext/test_serializer.py +++ b/test/ext/test_serializer.py @@ -1,13 +1,16 @@ +# coding: utf-8 from sqlalchemy.ext import serializer from sqlalchemy import testing from sqlalchemy import Integer, String, ForeignKey, select, \ - desc, func, util + desc, func, util, MetaData from sqlalchemy.testing.schema import Table from sqlalchemy.testing.schema import Column from sqlalchemy.orm import relationship, sessionmaker, scoped_session, \ class_mapper, mapper, joinedload, configure_mappers, aliased -from sqlalchemy.testing import eq_ +from sqlalchemy.testing import eq_, AssertsCompiledSQL +from sqlalchemy.util import u, ue +from sqlalchemy.engine import default from sqlalchemy.testing import fixtures @@ -19,7 +22,7 @@ class Address(fixtures.ComparableEntity): users = addresses = Session = None -class SerializeTest(fixtures.MappedTest): +class SerializeTest(AssertsCompiledSQL, fixtures.MappedTest): run_setup_mappers = 'once' run_inserts = 'once' @@ -173,6 +176,22 @@ class SerializeTest(fixtures.MappedTest): x = serializer.loads(ser, users.metadata) eq_(str(r), str(x)) + def test_unicode(self): + m = MetaData() + t = Table(ue('\u6e2c\u8a66'), m, + Column(ue('\u6e2c\u8a66_id'), Integer)) + + expr = select([t]).where(t.c[ue('\u6e2c\u8a66_id')] == 5) + + expr2 = serializer.loads(serializer.dumps(expr, -1), m) + + self.assert_compile( + expr2, + ue('SELECT "\u6e2c\u8a66"."\u6e2c\u8a66_id" FROM "\u6e2c\u8a66" ' + 'WHERE "\u6e2c\u8a66"."\u6e2c\u8a66_id" = :\u6e2c\u8a66_id_1'), + dialect=default.DefaultDialect() + ) + if __name__ == '__main__': testing.main()