From 6a38b502e08dae3430328e2eff557c638e042373 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 19 Oct 2006 07:20:52 +0000 Subject: [PATCH] - cleanup to the last commit - added contains_eager() MapperOption, used in conjunction with instances() to specify properties that should be eagerly loaded from the result set, using their plain column names by default, or translated given an custom row-translation function. [ticket:347]. --- CHANGES | 6 ++++++ lib/sqlalchemy/orm/interfaces.py | 4 ++-- lib/sqlalchemy/orm/query.py | 4 ++-- lib/sqlalchemy/orm/strategies.py | 6 ++---- test/orm/mapper.py | 12 +++++++----- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 23e3a78d83..95bd4bc65d 100644 --- a/CHANGES +++ b/CHANGES @@ -123,6 +123,12 @@ methods on MapperExtension have a slightly different method signature now as a result of the change; hoping that these methods are not in widespread use as of yet. + - instances() method moved to Query now, backwards-compatible + version remains on Mapper. + - added contains_eager() MapperOption, used in conjunction with + instances() to specify properties that should be eagerly loaded + from the result set, using their plain column names by default, or translated + given an custom row-translation function. - more rearrangements of unit-of-work commit scheme to better allow dependencies within circular flushes to work properly...updated task traversal/logging implementation diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 872164d325..8e505bac59 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -72,7 +72,6 @@ class StrategizedProperty(MapperProperty): self._all_strategies[cls] = strategy return strategy def setup(self, querycontext, **kwargs): - print "SP SETUP, KEY", self.key, " STRAT IS ", self._get_context_strategy(querycontext) self._get_context_strategy(querycontext).setup_query(querycontext, **kwargs) def execute(self, selectcontext, instance, row, identitykey, isnew): self._get_context_strategy(selectcontext).process_row(selectcontext, instance, row, identitykey, isnew) @@ -132,7 +131,8 @@ class StrategizedOption(PropertyOption): """a MapperOption that affects which LoaderStrategy will be used for an operation by a StrategizedProperty.""" def process_query_property(self, context, property): - print "HI " + self.key + " " + property.key + context.attributes[(LoaderStrategy, property)] = self.get_strategy_class() + def process_selection_property(self, context, property): context.attributes[(LoaderStrategy, property)] = self.get_strategy_class() def get_strategy_class(self): raise NotImplementedError() diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index a7021d4722..222eca5ac7 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -273,7 +273,7 @@ class Query(object): def execute(self, clauseelement, params=None, *args, **kwargs): result = self.session.execute(self.mapper, clauseelement, params=params) try: - return self.mapper.instances(result, self.session, with_options=self.with_options, **kwargs) + return self.instances(result, **kwargs) finally: result.close() @@ -283,7 +283,7 @@ class Query(object): session = self.session - context = SelectionContext(self.mapper, session, **kwargs) + context = SelectionContext(self.mapper, session, with_options=self.with_options, **kwargs) result = util.UniqueAppender([]) if mappers: diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 88d7f6c52e..84512c5a93 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -460,20 +460,18 @@ class EagerLoader(AbstractRelationLoader): try: # decorate the row according to the stored AliasedClauses for this eager load, # or look for a user-defined decorator in the SelectContext (which was set up by the contains_eager() option) - if selectcontext.attributes.has_key((EagerLoader, self)): + if selectcontext.attributes.has_key((EagerLoader, self.parent_property)): # custom row decoration function, placed in the selectcontext by the # contains_eager() mapper option - decorator = selectcontext.attributes[(EagerLoader, self)] + decorator = selectcontext.attributes[(EagerLoader, self.parent_property)] if decorator is None: decorated_row = row else: decorated_row = decorator(row) - print "OK! ROW IS", decorated_row else: # AliasedClauses, keyed to the lead mapper used in the query clauses = self.clauses_by_lead_mapper[selectcontext.mapper] decorated_row = clauses._decorate_row(row) - print "OK! DECORATED ROW IS", decorated_row # check for identity key identity_key = self.mapper.identity_key_from_row(decorated_row) except KeyError: diff --git a/test/orm/mapper.py b/test/orm/mapper.py index a048adbd87..4a401fde83 100644 --- a/test/orm/mapper.py +++ b/test/orm/mapper.py @@ -477,8 +477,9 @@ class MapperTest(MapperSuperTest): print u[0].orders[1].items[0].keywords[1] self.assert_sql_count(db, go, 3) sess.clear() - print "MARK" + print "-------MARK----------" u = q2.select() + print "-------MARK2----------" self.assert_sql_count(db, go, 2) class InheritanceTest(MapperSuperTest): @@ -874,7 +875,7 @@ class EagerTest(MapperSuperTest): {'user_id' : 9, 'addresses' : (Address, [])} ) - def testcustom(self): + def testcustomeagerquery(self): mapper(User, users, properties={ 'addresses':relation(Address, lazy=False) }) @@ -883,9 +884,10 @@ class EagerTest(MapperSuperTest): selectquery = users.outerjoin(addresses).select(use_labels=True) q = create_session().query(User) - l = q.options(contains_eager('addresses')).instances(selectquery.execute()) -# l = q.instances(selectquery.execute()) - self.assert_result(l, User, *user_address_result) + def go(): + l = q.options(contains_eager('addresses')).instances(selectquery.execute()) + self.assert_result(l, User, *user_address_result) + self.assert_sql_count(testbase.db, go, 1) def testorderby_desc(self): m = mapper(Address, addresses) -- 2.47.2