On Dec 7, 2006, at 11:48 PM, Daniel Miller wrote:
>
> I just looked at SA's PickleType and came up with a couple of issues.
>
SNIP
>
> 2. persistent_id/persistent_load
>
> I need to supply a custom pickler that will use persistent_id() and
> persistent_load(). These pickle extensions are natural requirements
> in a database environment. They allow objects that will be pickled
> to hold references to persistent objects and have those links
> automatically preserved across pickle/unpickle without actually
> pickling the persistent objects. However, there is no easy way to
> use these methods with SQLAlchemy--I'm referring specifically to
> the orm package here.
>
SNIP
>
> Now the obvious flaw here is that MyPickler needs a session at
> instantiation time, and it uses the same session for every unpickle
> throughout the entire application. From what I can tell PickleType
> has no way of getting at the session of the current load/save
> taking place when the data is selected from/written to the
> database. I'm not using thread-local sessions, so that won't work,
> however there are multiple concurrent sessions within my application.
>
> My other thought was to use a mapper extension to unpickle on
> populate_instance and pickle on before_insert/before_update. The
> session is easier to get there, and I might have been able to hack
> it somehow, but I had no way to tell the mapper to perform an
> update if the only thing that changed was the pickle data.
Upon further investigation of the mapper extension idea, I have
discovered that the problem is in the unit of work before it ever
gets to the mapper. When the UOW checks for changes with locate_dirty
() it doesn't find the objects with pickle data changes because that
won't actually get changed until before_insert or before_update,
which of course doesn't get called unless the UOW finds some changes
with locate_dirty(). It almost seems like there should be a mapper
extension point to check if an object is dirty.
attribute_manager.is_modified() would need to hook into that
extension point.
I think this problem would be really simple to solve if there was an
easy way to use a custom column property (i.e. an extended version of
sqlalchemy.orm.properties.ColumnProperty). There would be three
important methods:
class CustomProperty(ColumnProperty):
def getattr(self, object):
# get property value
def setattr(self, object, value):
# set property value
def get_history(self, object, passive=False):
# this one would need to be documented...what is history?
I'm having a hard time with that last one because it
ColumnProperty.get_history() calls attribute_manager.get_histroy()
and AttributeManager.get_history() calls getattr(obj.__class__,
key).get_history(), which seems to be to be a circular
relationship...it would be a lot simpler if the property could have a
method like:
def is_modified(self, object, oldvalue):
# return True if the current value of this
# property is different than oldvalue
Does history provide a more information than that?
~ Daniel
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---