- changed status to resolved
unpickle event in mutable requires hashing which might hit upon attribute access
Issue #2362
resolved
e.g.:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.mutable import MutableComposite
Base= declarative_base()
class Point(MutableComposite):
def __init__(self, x, y):
self.x = x
self.y = y
def __composite_values__(self):
return self.x, self.y
def __getstate__(self):
return self.x, self.y
def __setstate__(self, state):
self.x, self.y = state
def __setattr__(self, key, value):
"Intercept set events"
# set the attribute
object.__setattr__(self, key, value)
# alert all parents to the change
self.changed()
def __repr__(self):
return "Point(x=%r, y=%r)" % (self.x, self.y)
def __eq__(self, other):
return isinstance(other, Point) and \
other.x == self.x and \
other.y == self.y
def __ne__(self, other):
return not self.__eq__(other)
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
data = composite(Point, Column('x', Integer), Column('y', Integer))
def __eq__(self, other):
return self.id == other.id
import pickle
u1 = User(data=Point(3, 5))
pickle.loads(pickle.dumps(u1))
output:
Traceback (most recent call last):
File "test.py", line 57, in <module>
pickle.loads(pickle.dumps(u1))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1382, in loads
return Unpickler(file).load()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](key)(self)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1217, in load_build
setstate(state)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/state.py", line 191, in __setstate__
manager.dispatch.unpickle(self, state)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/event.py", line 274, in __call__
fn(*args, **kw)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/ext/mutable.py", line 413, in unpickle
val._parents[state.obj()](state.obj()) = key
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 262, in __setitem__
self.data[self._remove)](ref(key,) = value
File "test.py", line 51, in __eq__
return self.id == other.id
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/attributes.py", line 168, in __get__
return self.impl.get(instance_state(instance),dict_)
AttributeError: 'User' object has no attribute '_sa_instance_state'
simple patch:
diff -r 737456866c5f73452249cec0ccae9e9c4c5c545a lib/sqlalchemy/orm/state.py
--- a/lib/sqlalchemy/orm/state.py Fri Dec 30 15:29:44 2011 -0500
+++ b/lib/sqlalchemy/orm/state.py Fri Dec 30 23:56:40 2011 -0500
@@ -187,6 +187,7 @@
if 'load_path' in state:
self.load_path = interfaces.deserialize_path(state['load_path']('load_path'))
+ manager.setup_instance(inst, self)
manager.dispatch.unpickle(self, state)
def initialize(self, key):
Comments (2)
-
reporter -
reporter - removed milestone
Removing milestone: 0.7.5 (automated comment)
- Log in to comment
029ae72b2fffc5a69acf7fc610377cd0a148870e