]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
pickle example for dmiller
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 9 Dec 2006 00:09:14 +0000 (00:09 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 9 Dec 2006 00:09:14 +0000 (00:09 +0000)
examples/pickle/custom_pickler.py [new file with mode: 0644]

diff --git a/examples/pickle/custom_pickler.py b/examples/pickle/custom_pickler.py
new file mode 100644 (file)
index 0000000..34a2ff0
--- /dev/null
@@ -0,0 +1,82 @@
+"""illustrates one way to use a custom pickler that is session-aware."""
+
+from sqlalchemy import *
+from sqlalchemy.orm.session import object_session
+from cStringIO import StringIO
+from pickle import Pickler, Unpickler
+import threading
+
+meta = BoundMetaData('sqlite://', echo=True)
+
+class MyExt(MapperExtension):
+    def populate_instance(self, mapper, selectcontext, row, instance, identitykey, isnew):
+        MyPickler.sessions.current = selectcontext.session
+        return EXT_PASS
+    def before_insert(self, mapper, connection, instance):
+        MyPickler.sessions.current = object_session(instance)
+        return EXT_PASS
+    def before_update(self, mapper, connection, instance):
+        MyPickler.sessions.current = object_session(instance)
+        return EXT_PASS
+    
+class MyPickler(object):
+    sessions = threading.local()
+
+    def persistent_id(self, obj):
+        if getattr(obj, "id", None) is None:
+            sess = MyPickler.sessions.current
+            newsess = create_session(bind_to=sess.connection(class_mapper(Bar)))
+            newsess.save(obj)
+            newsess.flush()
+        key = "%s:%s" % (type(obj).__name__, obj.id)
+        return key
+
+    def persistent_load(self, key):
+        name, ident = key.split(":")
+        sess = MyPickler.sessions.current
+        return sess.query(Bar).get(ident)
+
+    def dumps(self, graph, protocol):
+        src = StringIO()
+        pickler = Pickler(src)
+        pickler.persistent_id = self.persistent_id
+        pickler.dump(graph)
+        return src.getvalue()
+
+    def loads(self, data):
+        dst = StringIO(data)
+        unpickler = Unpickler(dst)
+        unpickler.persistent_load = self.persistent_load
+        return unpickler.load()
+
+foo_table = Table('foo', meta, 
+    Column('id', Integer, primary_key=True),
+    Column('bar', PickleType(pickler=MyPickler()), nullable=False))
+
+bar_table = Table('bar', meta,
+    Column('id', Integer, primary_key=True),
+    Column('data', String(40)))
+
+meta.create_all()
+
+class Foo(object):
+    pass
+
+class Bar(object):
+    def __init__(self, value):
+        self.data = value
+    
+mapper(Foo, foo_table, extension=MyExt())
+mapper(Bar, bar_table)
+
+sess = create_session()
+f = Foo()
+f.bar = Bar('some bar')
+sess.save(f)
+sess.flush()
+sess.clear()
+
+del MyPickler.sessions.current
+
+f = sess.query(Foo).get(f.id)
+assert f.bar.data == 'some bar'
\ No newline at end of file