Data Inheritance

138 views
Skip to first unread message

laureano arcanio

unread,
Jul 16, 2008, 3:29:58 PM7/16/08
to sqlal...@googlegroups.com
Hi, I'm planning to implement Data inheritance for an os project i'm working on [1]. I have a model with a few tables and relationships between them ( not a complicated stuff ) and i was wandering if there is a way to accomplish data inheritance in an automated way ( i can eventually make a script to accomplish this )
I mind, given a Parent id, I'd like to copy it and get all child copied and "modified" too.

Does it possible ? if not, i will be manually doing it.. just making the whole model introspection by hand.. ( grr )

Any light on it would by great !

( I'm having problems to explain on English what I'm trying to do. sorry about it)

Thanks !

Michael Bayer

unread,
Jul 17, 2008, 9:52:12 AM7/17/08
to sqlal...@googlegroups.com


The general forms of "table inheritance" that SQLAlchemy supports
directly are described here: http://www.sqlalchemy.org/docs/05/mappers.html#advdatamapping_mapper_inheritance
.

laureano arcanio

unread,
Jul 17, 2008, 10:06:14 AM7/17/08
to sqlal...@googlegroups.com
Thanks Michael. I might not explain it well, but I've traying to make some kind of data ( rows ) inheritance, this is "copying" a table value and all it's related childrens, and modify it as necesary with new values in an automated way. ( not inherit Table structures )
 
It's looks weird i think, I'll acomplish some similar stuff mannually beacause i dont think this already exists, if it does i could not fint anything like this.
 
Thanks for your help. 
 

a...@svilendobrev.com

unread,
Jul 17, 2008, 4:07:56 PM7/17/08
to sqlal...@googlegroups.com

i am not sure i understand what u want, but here's my
baseDBclass.copy() method.

[ sidenote:
if u talk about real value inheritance/shading, that is different
quite complex beast, i have that too. e.g. A.x, B.x are values, B.a
points to some A, and Bs are before As in the value-inheritance
chain, so if A1.x=2, B1.a=A1 and B1.x=5, then inherited( B1.x) = 5
(e.g. shading); while if B1.x has no value, then inherited( B1.x)= 2
(e.g. inheritance or see-through).
]

here, i have objects with bitemporal versions, with bitemporal
many2many associations for most relations, hence any new version is a
semi-deep copy of previous + the modifications on top of that.

u can use this below as pseudocode/starting point to write your own -
plz ignore anything that makes no sense to you, or substitute with
your stuff of same meaning if u have such.

basicaly, logic is to copy all plain attributes and references, then
walk all relations and copy those, with the special case of explicit
associations, where the backlink of the copy of each member should be
explicitly set to the new owner.
Each item (plain or relation-member) is checked if it has to be
depth-copied or not.


class _NOTFOUND: pass

class Struct( _Base, ....):

dont_copy = [] # set of attr-names to ignore when copying;
#when inheriting dont miss the base set

dont_copy_me = False #copy as reference, not in depth;
# the copy wil refer same object


def copy( me, dont_copy_now =()):
if dbg: print l, 'copying', me

new = me.__class__()

#singulars
done = set()
for walker in [ me._walkTypes(), me._DBCOOK_references ]:
for name in walker:
if name in done: continue
done.add( name)
if name in dont_copy_now or name in me.dont_copy:
if dbg: print l, ' ignore', name
continue

item = getattr( me, name, _NOTFOUND)
if item is _NOTFOUND: #nothing to copy
if dbg: print l, ' ignore/novalue', name
continue

i0 = item
if not getattr( item, 'dont_copy_me', None):
vcopy = getattr( item, 'copy', None)
if callable( vcopy):
if dbg: print l, ' copy-deep', name, item
item = vcopy()
if dbg:
if i0 is item: print l, ' copy-ref', name
print l, ' copied', name, '=', item
setattr( new, name, item)


#maybe rels = [ p in class_mapper(klas).props if p.uselist ]
rels = getattr( me, '_DBCOOK_relations', () )
for name in rels:
if name in dont_copy_now or name in me.dont_copy:
if dbg: print l, ' ignore', name
continue

#make deep-copy of the set = set of copies of each item

child_klas = rels[ name]

if dbg: print l, ' copy-relation', name, ':', child_klas
children = getattr( me, name) #XXX this can load all!!
new_children = getattr( new, name)

explicit_assoc=not getattr( child_klas, 'DBCOOK_hidden',
True)
ab = about_relation( me.__class__, name)
attr = ab.otherside.name
for a in children:
#3 cases: non-assoc (nocopy), assoc.hidden (nocopy),
# assoc.explicit:copy
if explicit_assoc:
if dbg: print ' copy-deep-assoc', a
assert getattr( a, attr) is me
a = a.copy( dont_copy_now= [attr] )
if ab.no_backref:
if dbg: print ' replace', attr, new
setattr( a, attr, new)
else:
if dbg: print ' copy-ref'
if dbg: print ' copied-over', a
new_children.append( a )
if dbg: print l, ' copied-relation', name, new_children
return new

laureano arcanio

unread,
Jul 21, 2008, 8:37:00 AM7/21/08
to sqlal...@googlegroups.com
Yeah thats kind of what I'm trying to do, i think it would help me a little.

Thanks.



Reply all
Reply to author
Forward
0 new messages