From: Mike Bayer Date: Sun, 26 Mar 2006 07:21:28 +0000 (+0000) Subject: improved translation of rows when proxying rows from one mapper to another. X-Git-Tag: rel_0_1_5~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fcace31b887d0edb73dfd01a9134727d3647061f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git improved translation of rows when proxying rows from one mapper to another. --- diff --git a/examples/polymorph/polymorph2.py b/examples/polymorph/polymorph2.py index eebac80c18..fb9504fbed 100644 --- a/examples/polymorph/polymorph2.py +++ b/examples/polymorph/polymorph2.py @@ -73,7 +73,8 @@ person_join = select( column("'engineer'").label('type') ], people.c.person_id==engineers.c.person_id)).alias('pjoin') - + +print [c for c in person_join.c] # MapperExtension object. class PersonLoader(MapperExtension): @@ -87,10 +88,10 @@ class PersonLoader(MapperExtension): def populate_instance(self, mapper, instance, row, identitykey, imap, isnew): if row[person_join.c.type] =='engineer': - Engineer.mapper.populate_instance(instance, row, identitykey, imap, isnew) + Engineer.mapper.populate_instance(instance, row, identitykey, imap, isnew, frommapper=mapper) return False elif row[person_join.c.type] =='manager': - Manager.mapper.populate_instance(instance, row, identitykey, imap, isnew) + Manager.mapper.populate_instance(instance, row, identitykey, imap, isnew, frommapper=mapper) return False else: return True diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py index 32da013ac7..82257ae623 100644 --- a/lib/sqlalchemy/mapping/mapper.py +++ b/lib/sqlalchemy/mapping/mapper.py @@ -854,19 +854,27 @@ class Mapper(object): # call further mapper properties on the row, to pull further # instances from the row and possibly populate this item. if self.extension.populate_instance(self, instance, row, identitykey, imap, isnew): - self.populate_instance(instance, row, identitykey, imap, isnew, translate=False) + self.populate_instance(instance, row, identitykey, imap, isnew) if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing): if result is not None: result.append_nohistory(instance) return instance - def populate_instance(self, instance, row, identitykey, imap, isnew, translate=True): - if translate: - newrow = {} - for table in self.tables: - for c in table.c: - newrow[c] = row[c.key] - row = newrow + def translate_row(self, tomapper, row): + """attempts to take a row and translate its values to a row that can + be understood by another mapper. breaks the column references down to their + bare keynames to accomplish this. So far this works for the various polymorphic + examples.""" + newrow = util.DictDecorator(row) + for c in self.table.c: + newrow[c.key] = row[c] + for c in tomapper.table.c: + newrow[c] = newrow[c.key] + return newrow + + def populate_instance(self, instance, row, identitykey, imap, isnew, frommapper=None): + if frommapper is not None: + row = frommapper.translate_row(self, row) for prop in self.props.values(): prop.execute(instance, row, identitykey, imap, isnew)