On Thursday 17 July 2008 17:06:14 laureano arcanio wrote:
> 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.
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
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---