Commits

Mike Bayer committed 5121f24

synchronize inherited does not need to be called for the full mapper hierarchy

Comments (0)

Files changed (3)

examples/association/proxied_association.py

 
 metadata.create_all()
 
+class OrderItem(object):
+    def __init__(self, item, price=None):
+        self.item = item
+        self.price = price is None and item.price or price
+
 class Order(object):
     def __init__(self, customer_name):
         self.customer_name = customer_name
     items = AssociationProxy('itemassociations', 'item',
-                             creator=lambda x: OrderItem(x))
+                             creator=OrderItem)
 
 class Item(object):
     def __init__(self, description, price):
         self.description = description
         self.price = price
 
-class OrderItem(object):
-    def __init__(self, item, price=None):
-        self.item = item
-        self.price = price is None and item.price or price
 
 mapper(Order, orders, properties={
     'itemassociations':relation(OrderItem, cascade="all, delete-orphan", lazy=False)

lib/sqlalchemy/orm/mapper.py

                     mapper.__postfetch(uowtransaction, connection, table, state, c, c.last_inserted_params(), value_params)
 
                     # synchronize newly inserted ids from one table to the next
-                    # TODO: this fires off more than needed, try to organize syncrules
-                    # per table
-                    for m in reversed(list(mapper.iterate_to_root())):
-                        if m.__inherits_equated_pairs:
-                            m.__synchronize_inherited(state)
-
+                    # TODO: this performs some unnecessary attribute transfers
+                    # from an attribute to itself, since the attribute is often mapped
+                    # to multiple, equivalent columns
+                    if mapper.__inherits_equated_pairs:
+                        sync.populate(state, mapper, state, mapper, mapper.__inherits_equated_pairs)
+                        
                     # testlib.pragma exempt:__hash__
                     inserted_objects.add((state, connection))
 
                     if 'after_update' in mapper.extension.methods:
                         mapper.extension.after_update(mapper, connection, state.obj())
 
-    def __synchronize_inherited(self, state):
-        sync.populate(state, self, state, self, self.__inherits_equated_pairs)
-
     def __postfetch(self, uowtransaction, connection, table, state, resultproxy, params, value_params):
         """For a given Table that has just been inserted/updated,
         mark as 'expired' those attributes which correspond to columns

lib/sqlalchemy/orm/query.py

         return equivs
 
     def __no_criterion_condition(self, meth):
-        if self._criterion or self._statement or self._from_obj or self._limit is not None or self._offset is not None or self._group_by or self._order_by:
+        if self._criterion or self._statement or self._from_obj or \
+                self._limit is not None or self._offset is not None or \
+                self._group_by or self._order_by:
             raise sa_exc.InvalidRequestError("Query.%s() being called on a Query with existing criterion. " % meth)
 
         self._statement = self._criterion = self._from_obj = None