mς %&άGc@s dklZlZlZdklZdklZdZdZ dZ de fd„ƒYZ de fd „ƒYZ eie ƒe _d eifd „ƒYZd S( (ssqlsschemas exceptions(slogging(sutiliiitClauseSynchronizercBsAtZdZd„Zeed„Zd„Zeeed„ZRS(sžGiven a SQL clause, usually a series of one or more binary expressions between columns, and a set of 'source' and 'destination' mappers, compiles a set of SyncRules corresponding to that information. The ClauseSynchronizer can then be executed given a set of parent/child objects or destination dictionary, which will iterate through each of its SyncRules and execute them. Each SyncRule will copy the value of a single attribute from the parent to the child, corresponding to the pair of columns in a particular binary expression, using the source and destination mappers to map those two columns to object attributes within parent and child.cCs(||_||_||_g|_dS(N(t parent_mappertselft child_mappert directiont syncrules(RRRR((t7/home/holguin2/public_html/spyce/sqlalchemy/orm/sync.pyt__init__s   csq‡‡‡d†}tˆiƒ}t|ƒ}|i|ƒtˆiƒ|jot i dt |ƒƒ‚ndS(Nc sΈ|idjp.t|itiƒ pt|itiƒ odSnd}d}ˆdj oΠ|ii |ii joc|ii o|i}|i}q+|ii o|i}|i}q+t idt|ƒƒ‚qΓ|iˆjo|i}|i}qΓ|iˆjo|i}|i}qΓdSn•|ig}|iiD]}||iqF~jo|i}|i}nK|ig}|iiD]}||iq~jo|i}|i}n|oκ|oγˆitjo,ˆiitˆi||dˆiƒƒq΄ˆitjo,ˆiitˆi||dˆiƒƒq΄ˆp2ˆiitˆi||dˆidˆƒƒq΄ˆiitˆi||dˆidˆƒƒndS(s3assemble a SyncRule given a single binary conditiont=NsJCan't locate a primary key column in self-referential equality clause '%s't dest_mappert issecondary(tbinarytoperatort isinstancetlefttschematColumntrighttNonet source_columnt dest_columnt foreignkeyttablet primary_keyt exceptionst ArgumentErrortstrt_[1]t foreign_keystftcolumnRRt ONETOMANYRtappendtSyncRuleRRt MANYTOONER (R RRRR(RRR (Rtcompile_binary#sF>           4  4  ,,2s*No syncrules generated for join criterion ( R#tlenRRt rules_addedt BinaryVisitort processort sqlclausetaccept_visitorRRR(RR(R RR#R%R'((RR RRtcompile"s 2  cCs9g}|iD]$}|idj o||iqq~S(N(RRRtrRR(RRR+((Rt dest_columns[scCs1x*|iD]}|i|||||ƒq WdS(N( RRtruletexecutetsourcetdesttobjtchildt clearkeys(RR/R0R1R2R3R-((RR.^s (t__name__t __module__t__doc__RRR*R,R.(((RRs  9 R!cBs/tZdZeed„Zd„Zd„ZRS(sHAn instruction indicating how to populate the objects on each side of a relationship. i.e. if table1 column A is joined against table2 column B, and we are a one-to-many from table1 to table2, a syncrule would say 'take the A attribute from object1 and assign it to the B attribute on object2'. A rule contains the source mapper, the source column, destination column, destination mapper in the case of a one/many relationship, and the integer direction of this mapper relative to the association in the case of a many to many relationship. cCs1||_||_||_||_||_dS(N(t source_mapperRRR R R(RR7RRR R ((RRms     cCs^y |iSWnLtj o@|idj o|i|ii|iij|_|iSnXdS(N(Rt_dest_primary_keytAttributeErrorR RRt pks_by_tableR(R((Rtdest_primary_keyus  2cCs]|djo8|itjo |}qE|itjo |}qEn|p |djo d}n|i i ||i ƒ}t |tƒo|||ii%s(%s) ('%s')(R/RRR tFalseR1tTrueR2R3tvalueR7tget_attr_by_columnRR R0tdictRtkeyR;RtAssertionErrorRt mapperutilt instance_strtloggingtis_debug_enabledtloggertdebugR tset_attr_by_column(RR/R0R1R2R3R>((RR.|s   /K(R4R5R6RRR;R.(((RR!bs  R&cBstZd„Zd„ZRS(NcCs ||_dS(N(tfuncR(RRJ((RR“scCs|i|ƒdS(N(RRJR (RR ((Rt visit_binary•s(R4R5RRK(((RR&’s N(t sqlalchemytsqlRRREtsqlalchemy.ormtutilRCRR"t MANYTOMANYtobjectRR!t class_loggerRGt ClauseVisitorR&( RERR"RPRR&RMRRCR!R((Rt? s  N.