insert/update statement compilation process in terms of the column names
present but not the values for those columns. Produces more consistent
execute/executemany behavior, simplifies things a bit internally.
+
+- added 'comparator' keyword argument to PickleType. By default, "mutable"
+ PickleType does a "deep compare" of objects using their dumps() representation.
+ But this doesn't work for dictionaries. Pickled objects which provide an
+ adequate __eq__() implementation can be set up with "PickleType(comparator=operator.eq)"
+ [ticket:560]
- Fixed reflection of the empty string for mysql enums.
class PickleType(MutableType, TypeDecorator):
impl = Binary
- def __init__(self, protocol=pickle.HIGHEST_PROTOCOL, pickler=None, mutable=True):
+ def __init__(self, protocol=pickle.HIGHEST_PROTOCOL, pickler=None, mutable=True, comparator=None):
self.protocol = protocol
self.pickler = pickler or pickle
self.mutable = mutable
+ self.comparator = comparator
super(PickleType, self).__init__()
def bind_processor(self, dialect):
return value
def compare_values(self, x, y):
- if self.mutable:
+ if self.comparator:
+ return self.comparator(x, y)
+ elif self.mutable:
return self.pickler.dumps(x, self.protocol) == self.pickler.dumps(y, self.protocol)
else:
return x is y
),
])
-
def test_nocomparison(self):
"""test that types marked as MutableType get changes detected on them when the type has no __eq__ method"""
class Foo(object):pass
def go():
Session.commit()
self.assert_sql_count(testbase.db, go, 0)
+
+class MutableTypesTest2(ORMTest):
+ def define_tables(self, metadata):
+ global table
+ import operator
+ table = Table('mutabletest', metadata,
+ Column('id', Integer, Sequence('mutableidseq', optional=True), primary_key=True),
+ Column('data', PickleType(comparator=operator.eq)),
+ )
+
+ def test_dicts(self):
+ """dictionaries dont pickle the same way twice, sigh."""
+
+ class Foo(object):pass
+ mapper(Foo, table)
+ f1 = Foo()
+ f1.data = [{'personne': {'nom': u'Smith', 'pers_id': 1, 'prenom': u'john', 'civilite': u'Mr', \
+ 'int_3': False, 'int_2': False, 'int_1': u'23', 'VenSoir': True, 'str_1': u'Test', \
+ 'SamMidi': False, 'str_2': u'chien', 'DimMidi': False, 'SamSoir': True, 'SamAcc': False}}]
+
+ Session.commit()
+ def go():
+ Session.commit()
+ self.assert_sql_count(testbase.db, go, 0)
+
+ f1.data = [{'personne': {'nom': u'Smith', 'pers_id': 1, 'prenom': u'john', 'civilite': u'Mr', \
+ 'int_3': False, 'int_2': False, 'int_1': u'23', 'VenSoir': True, 'str_1': u'Test', \
+ 'SamMidi': False, 'str_2': u'chien', 'DimMidi': False, 'SamSoir': True, 'SamAcc': False}}]
+
+ def go():
+ Session.commit()
+ self.assert_sql_count(testbase.db, go, 0)
+
+ f1.data[0]['personne']['VenSoir']= False
+ def go():
+ Session.commit()
+ self.assert_sql_count(testbase.db, go, 1)
+ Session.clear()
+ f = Session.query(Foo).get(f1.id)
+ assert f.data == [{'personne': {'nom': u'Smith', 'pers_id': 1, 'prenom': u'john', 'civilite': u'Mr', \
+ 'int_3': False, 'int_2': False, 'int_1': u'23', 'VenSoir': False, 'str_1': u'Test', \
+ 'SamMidi': False, 'str_2': u'chien', 'DimMidi': False, 'SamSoir': True, 'SamAcc': False}}]
class PKTest(ORMTest):
def define_tables(self, metadata):