Object Databases

Marc POINOT poinot at onera.fr
Wed Mar 1 04:07:16 EST 2000


"Andrew M. Kuchling" wrote:
> 
> 3) SQL databases.  Pros: common, well-known technology, from
> established companies like Oracle and IBM; lots of other software for
> them.  Downsides: storing objects is clunky, requiring writing lots of
> boring save/load code, and many joins are needed to read in an object.
> We could write something like Tangram to save us from writing boring
> code, but that won't help the run-time speed problem.
> 
I don't know about Tangram but I'm certainly interested in such
a tool.

> Anyone had to tackle a similar problem?
> 
We're using point [3]. First, it is more easy to find a developper
that already knows SQL and RDBMS, second we have no OODBMS here :) 

Now, the obvious problem is to maintain.
When your object description changes, when you want to modify your
schema (e.g. reuse tables comming from new object, making joins and 
trying to factorize both code/data), you have to change both the class
and the schema. We cannot work on an class-mapping basis because we
think
we have to modify to the schema as a whole.
We have a kind of table/object description which is expected
(suspected?) 
to make this easier, but as a matter of fact it is not.

Just to make you shiver (cry? laugh?), I send piece of code for
a table description. Hint: an object is hidden in there...

d_pr_keys={ wtNAME   : 'Keywords',  
            wtTEXT   : "Keywords for all tools", 
wtTITLES :[ 'id', 'text', 'level', 'comment' ],
wtSIZE   :[  20,   180,    40,      500      ],
wtFORMAT :[  '%d', '%s',   '%d',    '%s'     ],
wtWRITE  :[  0,    1,      1,       1        ],
wtORDCOL :[  2,    1,      3,       0        ],
wtRELSHP :{ # prim-key readrequest listrequest addrequest delrequest
 'test'   : [ 0,       qySuiteTT,  qyList_TT,  None,      None]
},
wtJOINREF:[ #   id->value      list values      value->id
            0,                                                   # id
            0,                                                   # date
            0,                                                   # mail
            0,                                                   #
answer
            0,                                                   #
abstract
            [  qyPRTToText,    qyList_PRT,      qyTextToPRT ],   # type
            [  qyCSTToText,    qyList_CST,      qyTextToCST ],   #
contact
            [  qyPRSToText,    qyList_PRS,      qyTextToPRS ],   #
status 
            [  qyPRPToText,    qyList_PRP,      qyTextToPRP ],   # mode
            [  qyVRSToText,    qyList_VRS,      qyTextToVRS ]    #
version
],
wtREQUEST:{
 'list'   : qyList_KW,
 'fill'   : qyAll_KW,
 'reload' : [upDrivePR.reloadPR],
 'last'   : """select max(id) from prKeyList""",
 'oneW'   : """update prKeyList set
text='%(text)s',level=%(level)d,comment='%(comment)s' where id=%(id)d"""
,
 'add'    : """insert into prKeyList(id,text,level,comment)
values(%(id)d,'%(text)s',%(level)d,'%(comment)s')"""
}
}

fillOneEmpty(d_pr_keys, 4)

It's a dictionnary based structure, where some predefined actions
are mapped to SQL calls.
wtRELSHP manages the relationships with objects. In other words, it
makes a join with other objects ids, it's a kind of simulated
aggregate. The variables like qy* are predefined queries,
such as:

qyTKTToText : ["select text from wType where type=?" ,],
qyTextToTKT : ["select type from wType where text=?" ,],
qyTKSToText : ["select text from wStatus where type=?" ,],
qyTextToTKS : ["select type from wStatus where text=?" ,],
qyUSRToText : ["select id from dpeople where name=?" ,],
qyTextToUSR : ["select name from dpeople where id=?" ,],

The wtJOINREF table is used for "enumerates". When you
have a table (here, there is a mix with PR (Problem reports)
and KW (keywords) tables), that referes to enumerates, the
wtJOINREF gives you the way to get/set/list the value
wrt the id.

The last call to fillOneEmpty checks the dictionnary and
fills missing entries with default values.
This system is very heavy. Moreover, it is not our job, it is
a layer below our actual job. I mean the application actually
uses the objects that are stored below this layer, but we
are spending most of the time maintening this translation layer.

We also have a problem with large transactions, as a lot of tables are
modified and the update propagation to "open" objects if actually
much larger than expected. Thus, we have to use table timestamps
to avoid large updates (I mean client/server update, because the
object itself is on client, and the server delivers tables...).

We also had some experience with pickle, but this requires major
adds to make it ACID... psssshhhh

Marcvs [alias Thanks for any comment. Especially comments like:
        Hey guy, you can do your #&@^# 25 description lines here 
        in a single one!]




More information about the Python-list mailing list