diff options
Diffstat (limited to 'lib/sqlalchemy/mapping')
| -rw-r--r-- | lib/sqlalchemy/mapping/mapper.py | 36 | ||||
| -rw-r--r-- | lib/sqlalchemy/mapping/properties.py | 3 |
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py index 5e0f25738..5b56358ba 100644 --- a/lib/sqlalchemy/mapping/mapper.py +++ b/lib/sqlalchemy/mapping/mapper.py @@ -291,7 +291,7 @@ class Mapper(object): objectstore.get_session().register_clean(value) if mappers: - result.extend(otherresults) + result = [result] + otherresults return result def get(self, *ident): @@ -837,8 +837,8 @@ class Mapper(object): # call further mapper properties on the row, to pull further # instances from the row and possibly populate this item. - for prop in self.props.values(): - prop.execute(instance, row, identitykey, imap, isnew) + if self.extension.populate_instance(self, instance, row, identitykey, imap, isnew): + self.populate_instance(instance, row, identitykey, imap, isnew, translate=False) if self.extension.append_result(self, row, imap, result, instance, isnew, populate_existing=populate_existing): if result is not None: @@ -846,6 +846,17 @@ class Mapper(object): 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 + + for prop in self.props.values(): + prop.execute(instance, row, identitykey, imap, isnew) + class MapperProperty(object): """an element attached to a Mapper that describes and assists in the loading and saving of an attribute on an object instance.""" @@ -930,7 +941,8 @@ class MapperExtension(object): def append_result(self, mapper, row, imap, result, instance, isnew, populate_existing=False): """called when an object instance is being appended to a result list. - If it returns True, it is assumed that this method handled the appending itself. + If this method returns True, it is assumed that the mapper should do the appending, else + if this method returns False, it is assumed that the append was handled by this method. mapper - the mapper doing the operation @@ -956,6 +968,22 @@ class MapperExtension(object): return True else: return self.next.append_result(mapper, row, imap, result, instance, isnew, populate_existing) + def populate_instance(self, mapper, instance, row, identitykey, imap, isnew): + """called right before the mapper, after creating an instance from a row, passes the row + to its MapperProperty objects which are responsible for populating the object's attributes. + If this method returns True, it is assumed that the mapper should do the appending, else + if this method returns False, it is assumed that the append was handled by this method. + + Essentially, this method is used to have a different mapper populate the object: + + def populate_instance(self, mapper, *args): + othermapper.populate_instance(*args) + return False + """ + if self.next is None: + return True + else: + return self.next.populate_instance(row, imap, result, instance, isnew) def before_insert(self, mapper, instance): """called before an object instance is INSERTed into its table. diff --git a/lib/sqlalchemy/mapping/properties.py b/lib/sqlalchemy/mapping/properties.py index e5bcee78c..334054233 100644 --- a/lib/sqlalchemy/mapping/properties.py +++ b/lib/sqlalchemy/mapping/properties.py @@ -807,11 +807,14 @@ class EagerLoader(PropertyLoader): if map.has_key(key): key = map[key] return self.row[key] + def keys(self): + return map.keys() map = {} for c in self.eagertarget.c: parent = self.target._get_col_by_original(c.original) map[parent] = c map[parent._label] = c + map[parent.name] = c return DecoratorDict def _instance(self, row, imap, result_list=None): |
