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

Reply via email to