Object Database (ODBMS) for Python

Patrick K. O'Brien pobrien at orbtech.com
Fri Aug 29 13:50:55 EDT 2003


"Paul D. Fernhout" <pdfernhout at kurtz-fernhout.com> writes:

> By the way, if you add support for the sorts of associative tuples
> with the Pointrel System is based on, efficiently managed, maybe
> I'll consider switching to using your system, if the API is simple
> enough. :-) Or, perhaps there is a way the Pointrel System can be
> extended to support what you might want to do (in the sense of
> transparent interaction with Python). In its use of the pickler, the
> Pointrel System does not keep a list of previously pickled object,
> so it can't transparently pickle objects that refer to previously
> pickled object in the repository, so that is one way that the
> Pointrel system can't do what your system does at all. (I'm not sure
> how to do that without like PyPerSyst keeping lots of previously
> pickled objects in memory at once for the Pickler to work
> with). Also, in the Pointrel System repositories are sort of on the
> fly made up of an arbitrary collection of archives where archives
> may be added and removed dynamically, so I don't quite begin to see
> to handle object persistance across a repository if subobjects are
> stored in different archives which are dropped out of the
> repository.

Oy!  There we go with the API thing again.  ;-)

PyPerSyst can manage anything that can be pickled.  So it should be
able to support your associative tuples.  But to get the most bang for
your buck, you'd want to subclass the Entity class that I recently
added to PyPerSyst.  I can't think of a reason it wouldn't work, but
we'd have to give it a try and see.

The root of a PyPerSyst database can be any Python object graph, with
any kind of object referencing that Python supports.  But transactions
must be deterministic and independent, so they cannot contain
references.  If you saw my examples of the generic transactions you'll
see that I passed in references.  How can that be?  The secret is the
dereferencing that takes place in those transaction classes:

"""Generic transactions."""

__author__ = "Patrick K. O'Brien <pobrien at orbtech.com>"
__cvsid__ = "$Id: transaction.py,v 1.8 2003/08/27 00:53:01 pobrien Exp $"
__revision__ = "$Revision: 1.8 $"[11:-2]


from pypersyst.entity.entity import Entity
from pypersyst.transaction import Transaction


class Create(Transaction):

    def __init__(self, classname, **attrs):
        Transaction.__init__(self)
        self.classname = classname
        self.attrs = attrs

    def __getstate__(self):
        self.refs = {}
        for name, value in self.attrs.items():
            if isinstance(value, Entity):
                self.refs[name] = (value.__class__.__name__, value.oid)
                self.attrs[name] = None
        return self.__dict__.copy()

    def execute(self, root):
        self.EntityClass = root._classes[self.classname]
        for name, (classname, oid) in self.refs.items():
            self.attrs[name] = root[classname][oid]
        return self.EntityClass(**self.attrs)


class Delete(Transaction):

    def __init__(self, instance):
        Transaction.__init__(self)
        self.instance = instance

    def __getstate__(self):
        self.classname = self.instance.__class__.__name__
        self.oid = self.instance.oid
        d = self.__dict__.copy()
        del d['instance']
        return d

    def execute(self, root):
        return root[self.classname]._delete(self.oid)


class Update(Transaction):

    def __init__(self, instance, **attrs):
        Transaction.__init__(self)
        self.instance = instance
        self.attrs = attrs

    def __getstate__(self):
        self.classname = self.instance.__class__.__name__
        self.oid = self.instance.oid
        self.refs = {}
        for name, value in self.attrs.items():
            if isinstance(value, Entity):
                self.refs[name] = (value.__class__.__name__, value.oid)
                self.attrs[name] = None
        d = self.__dict__.copy()
        del d['instance']
        return d

    def execute(self, root):
        self.instance = root[self.classname][self.oid]
        for name, (classname, oid) in self.refs.items():
            self.attrs[name] = root[classname][oid]
        return root[self.classname]._update(self.instance, **self.attrs)


Try telling me that isn't one sweet API!  ;-)

-- 
Patrick K. O'Brien
Orbtech      http://www.orbtech.com/web/pobrien
-----------------------------------------------
"Your source for Python programming expertise."
-----------------------------------------------




More information about the Python-list mailing list