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 sqlalchemy@googlegroups.com
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to