Re: [Modeling-users] Foreign Keys
Status: Abandoned
Brought to you by:
sbigaret
|
From: Sebastien B. <sbi...@us...> - 2003-07-23 16:44:42
|
Okay, so:
1. when you're saving the db into xml, you want to avoid saving objects in
relations (I presume that's why 'i18n' e.g. is hard-coded),
2. when restoring, you have to find back the objects in relations.
About 1: I saw you're using CustomObject.snapshot(). Note that since
fetchRawRow() exists, you also have a method CustomObject.snapshot_raw()
at hand which returns the row corresponding to the object (and this one
is exactly the same one than the one you'd get with fetch and parameter
rawRows=3D1). So, as expected, you get the PK and the FKs defined for the
corresp. entity, *no matter* whether they are class properties or not.
(And yes, it should be documented :)
Now for restoring, I must be possible to do something like this:
- initialize and populate each object, store them in a dictionary with
something like=20
rootEntityName=3Dentity.rootEntity().name() #this makes it easier
#if you use inheritance
d[rootEntityName+'_%i'%pk]=3Dobject
- then iterate on your objects and fill the relations, just as you do,
except that you'll avoid the slow xpath query. Instead, you'll
iterate on your i18ns and find the corresponding master object with
a simple lookup in the dictionary, because the master will be:
rootEntityName_master=3D...
master=3Dd[rootEntityName_master+'_%i'%i18n._fk_master]
given that the fk is stored in the i18n._fk_master
> So skiping PKs would be much more simple
In fact, your problem here is not exactly to set a PK you generate
yourself, but to match an object's FK w/ an other object's PK, which
is not exactly the same pb. and cannot be easily solved.
> but having the framework
> doing the dump and restoration would be even beter. I do the dump
> like this (phpMyAdmin is full Latin-1) :
In fact, yes, this would be better, for example with serialization of
EditingContext. Not done however...
Last, I don't know why you insist on dumping/restoring your db w/ the
framework, but that's not the most efficient way of doing this, is it?-)
Maybe you should consider dumping and restoring raw sql (postgresql can
dump a whole database in a text file). In this case, the only thing
you'll have to take care of wrt the framework is that sequences
supporting PK generation (you're using postgresql, right?) get the right
value before trying to insert new objects (the sequence should start at
max(id)+1 for a given table, or, if you're using inheritance, to the
max(id) of the different tables involved in an inheritance tree --there
is one and only one sequence used for generating the pks per root
entity).
-- S=E9bastien.
Yannick Gingras <yan...@sa...> wrote:
> Ehh humm like this :
>=20
> exec ("global %s" % childClassName)
> exec (importCmd % (childClassName, childClassName))
>=20=20=20=20=20=20=20=20=20
> posElem =3D xpath.Evaluate(("./%s/text()" % fkStr), elem)[0]
> curPos =3D int(posElem.nodeValue)
>=20
> i18nPath =3D '/db_dump/%s[%s/text()=3D"%d"]' % ( childClassNa=
me,
> fkStr,
> curPos )
> i18nElems =3D xpath.Evaluate(i18nPath, self.i18nDoc)
>=20=20=20=20=20=20=20=20=20=20=20=20=20
> # create i18ns
> for i18nElem in i18nElems:
> i18nObj =3D eval("%s()" % childClassName)
> self.fillObject(i18nObj, i18nElem)
> obj.addObjectToBothSidesOfRelationshipWithKey(i18nObj, 'i=
18n')
> self.ec.insertObject(i18nObj)
> self.ec.insertObject(obj)
>=20
>=20
> I process the table dumps 2 by 2, one for the master, one for i18ns.
> I must admit that I don't know how I will restore the more complex
> relations. The way I do it now fix the missing PKs problem because I
> find the matching ones in the i18n dump with i18nPath but it's a hack,
> a really slow hack. I have to do a XPath query on a 1400 nodes file
> 700 time : 300 secs avg.
>=20
> So skiping PKs would be much more simple but having the framework
> doing the dump and restoration would be even beter. I do the dump
> like this (phpMyAdmin is full Latin-1) :
>=20
> if __name__ =3D=3D "__main__":
> if not len(sys.argv) =3D=3D 2:
> print "USAGE : dump_xml.py <entity-name>"
> sys.exit(1)
>=20
> sys.path.append("..")
>=20=20=20=20=20
> entityName =3D sys.argv[1]
> ec =3D EditingContext()
> mm =3D ModelManager(ec)
>=20
> importCmd =3D "from Autogen.%s import %s" % (entityName, entityName)
> exec(importCmd)
>=20
> objs =3D mm.fetch(entityName)
>=20
> # get the primary key name
> key =3D ec.globalIDForObject(objs[0]).keyValues().keys()[0]
>=20=20=20=20=20
> objs =3D map(lambda obj:mm.snapshot(obj), objs)
>=20
> objs =3D sortById(objs, key)
>=20
> domDoc =3D getDomDoc()
> for obj in objs:
> elem =3D domDoc.createElement(entityName)
> for key in obj.keys():
> tagName =3D externalNameForInternalName(key).lower()
> property =3D domDoc.createElement(tagName)
> if key !=3D "i18n":
> elem.appendChild(property)
> dataStr =3D toStr(obj[key])
> data =3D domDoc.createTextNode(dataStr)
> property.appendChild(data)
> xpath.Evaluate("/db_dump", domDoc)[0].appendChild(elem)
>=20=20=20=20=20
> PrettyPrint(domDoc)
>=20
>=20
> Yes, i18n is hardcoded... : \
>=20
> --=20
> Yannick Gingras
> Byte Gardener, Savoir-faire Linux inc.
> (514) 276-5468
|