From 3bb71bdd2d36afcb024ef413f197887a8a3883a5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 16 Oct 2006 17:20:15 +0000 Subject: [PATCH] strings and unicodes are compared via == rather than 'is'. TypeDecorator uses underlying impl for mutator/comparison functions by default --- lib/sqlalchemy/types.py | 9 ++++++++- test/orm/unitofwork.py | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 9ce36cffdb..1a30bc5cd5 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -98,6 +98,12 @@ class TypeDecorator(AbstractType): return instance def get_dbapi_type(self, dbapi): return self.impl.get_dbapi_type(dbapi) + def copy_value(self, value): + return self.impl.copy_value(value) + def compare_values(self, x, y): + return self.impl.compare_values(x,y) + def is_mutable(self): + return self.impl.is_mutable() class MutableType(object): """a mixin that marks a Type as holding a mutable object""" @@ -144,7 +150,6 @@ class NullTypeEngine(TypeEngine): def convert_result_value(self, value, dialect): return value - class String(TypeEngine): def __new__(cls, *args, **kwargs): if cls is not String or len(args) > 0 or kwargs.has_key('length'): @@ -167,6 +172,8 @@ class String(TypeEngine): return value.decode(dialect.encoding) def get_dbapi_type(self, dbapi): return dbapi.STRING + def compare_values(self, x, y): + return x == y class Unicode(TypeDecorator): impl = String diff --git a/test/orm/unitofwork.py b/test/orm/unitofwork.py index debf63ce38..f9b512af15 100644 --- a/test/orm/unitofwork.py +++ b/test/orm/unitofwork.py @@ -239,7 +239,8 @@ class MutableTypesTest(UnitOfWorkTest): metadata = BoundMetaData(testbase.db) table = Table('mutabletest', metadata, Column('id', Integer, primary_key=True), - Column('data', PickleType, nullable=False)) + Column('data', PickleType), + Column('value', Unicode(30))) table.create() def tearDownAll(self): table.drop() @@ -279,6 +280,22 @@ class MutableTypesTest(UnitOfWorkTest): print f2.data, f3.data assert (f3.data.x, f3.data.y) == (4,19) + def testunicode(self): + """test that two equivalent unicode values dont get flagged as changed. + + apparently two equal unicode objects dont compare via "is" in all cases, so this + tests the compare_values() call on types.String and its usage via types.Unicode.""" + class Foo(object):pass + mapper(Foo, table) + f1 = Foo() + f1.value = u'hi' + ctx.current.flush() + ctx.current.clear() + f1 = ctx.current.get(Foo, f1.id) + f1.value = u'hi' + def go(): + ctx.current.flush() + self.assert_sql_count(db, go, 0) class PKTest(UnitOfWorkTest): -- 2.47.2