Object Database (ODBMS) for Python

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


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

> Well, to chime in here, in a "friendly" competition / cooperation

Let me start by saying I'd love to cooperate, even if I am competitive
by nature.  ;-)

Please keep that in mind as I agree/disagree with some of your
points.  ;-)

> sort of way, the Pointrel Data Repository System,
>    http://sourceforge.net/projects/pointrel/
> while not quite an object database (and admittedly its case being
> easier) has a simple API in the bare minimum use case (it has more
> complex variants). Here is an example of its use (with fragments
> inspired in response to an earlier c.l.p poster's use case a few days
> ago):
> 
>    from pointrel20030812 import *
> 
>    # add a first attendant -- uses built in unique ID function
>    # each change will be implicitely a seperate transaction
>    attendantID = Pointrel_generateUniqueID()
>    Pointrel_add("congress", attendantID, 'object type', 'user')
>    Pointrel_add("congress", attendantID, 'name', 'Sir Galahad')
> 
>    # add a second attendant, this time as an atomic transaction
>    attendantID = Pointrel_generateUniqueID()
>    Pointrel_startTransaction()
>    Pointrel_add("congress", attendantID, 'object type', 'user')
>    Pointrel_add("congress", attendantID, 'name', 'Brian')
>    Pointrel_finishTransaction()
> 
> In the first case, the changes are automatically made into
> transactions, in the second, they are lumped under the current
> transaction.
> 
> Note that Python objects could be added to the database, as in:
> 
>    Pointrel_add("test", 10, ["hello", "goodbye"], MyClass)
> 
> This simple API is made possible by two decisions:

This API looks rather verbose to me.  I think mine would look like:

>>> t = tx.Create('User', name='Sir Galahad')
>>> user = db.execute(t)

And unique ids (immutable, btw) are assigned by PyPerSyst:

>>> user.oid
42

And you can still access attributes directly, you just can't change
them outside of a transaction:

>>> user.name
'Sir Galahad'

And the generic Update transaction is equally simple:

>>> t = tx.Update(user, name='Brian')
>>> db.execute(t)
>>> user.name
'Brian'

> Granted, the Pointrel System is essentially a single user single
> transaction system at the core. It (in theory, subject to bugs)
> supports atomicity (transactions), isolation (locking) and
> durability (logging&recovery). It only supports consistency by how
> applications use transactions as opposed to explicit constraints or
> rules maintained by the database, so one could argue it fails the
> ACID test there. (Although would any typical ODBMS pass consistency
> without extra code support? Does PyPerSyst have this as the database
> level?)

PyPerSyst can persist *any* picklable object graph.  But it also comes
with an Entity class and a Root class (that understands Entity
classes) that provides additional functionality, such as alternate
indexes, referential integrity, instance validation, etc.  So if your
schema describes classes that subclass Entity, you get lots of
functionality built into the database itself, without having to write
any additional code, other than the additional validity checking that
only your subclass knows.  But I'd like to make more of that
declarative as well.  I'm also working on Fields, which provide
validation and other features at the individual Entity attribute
level.  Fields have lots of metadata, like fields in an RDBMS.

My goal is to have as much behavior as possible in the database, and
have that behavior controlled declaratively within the schema.

> To be clear, I'm not holding this out as "Pointrel System great" and
> "PyPerSystem not so great", since obviously the two systems do
> different things, each have its own focus, your task is perhaps
> harder, I don't fully understand everything that is going on here in
> your design and requirements, etc. What I am trying to get at is
> more to challenge you (in a friendly way) to have a very simple API
> in a default case by throwing down a pseudo-gauntlet of a simpler
> system API.

I don't mind a friendly challenge.  I'm just surprised that the bulk
of this thread is debating an API that has barely seen the light of
day, and that I consider to be drop-dead simple.  I guess I need to
get a demo app created soon, just to put this to rest.  Or at least
make sure we're all debating about the same thing.  ;-)

Right now we're debating an API that nobody on this thread has really
seen or used, other than me.  The other thing I can say is that, imo,
the way you interact with persistent class instances is not the same
way you interact with regular class instances.  Not if you value the
integrity and reliability of your data.  And trying to make it appear
so is a disservice.  I know everyone seems to think transparent
persistence is the holy grail, but I've come to think otherwise.

Unfortunately, I don't have time to fully elaborate my position.  But
you don't have to agree with me on this point.  PyPerSyst is very
modular, and there implementations of transparent proxies in the
PyPerSyst CVS sandbox that some other developers on the team have
written.  So it can be done.

I'll reply to other stuff separately to keep the message size down.

-- 
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