From: Mike Bayer Date: Sat, 9 Dec 2006 00:09:14 +0000 (+0000) Subject: pickle example for dmiller X-Git-Tag: rel_0_3_2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=226baafe60309964776564e40970c3778131eb9e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git pickle example for dmiller --- diff --git a/examples/pickle/custom_pickler.py b/examples/pickle/custom_pickler.py new file mode 100644 index 0000000000..34a2ff0e59 --- /dev/null +++ b/examples/pickle/custom_pickler.py @@ -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