diff options
-rw-r--r-- | lib/sqlalchemy/ext/baked.py | 19 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/interfaces.py | 28 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/strategy_options.py | 89 | ||||
-rw-r--r-- | test/aaa_profiling/test_orm.py | 41 | ||||
-rw-r--r-- | test/ext/test_baked.py | 9 | ||||
-rw-r--r-- | test/orm/test_options.py | 800 | ||||
-rw-r--r-- | test/profiles.txt | 22 |
7 files changed, 16 insertions, 992 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index 4f40637c5..ecbf871e2 100644 --- a/lib/sqlalchemy/ext/baked.py +++ b/lib/sqlalchemy/ext/baked.py @@ -194,18 +194,13 @@ class BakedQuery(object): if not cache_path: cache_path = effective_path - if cache_path.path[0].is_aliased_class: - # paths that are against an AliasedClass are unsafe to cache - # with since the AliasedClass is an ad-hoc object. - self.spoil(full=True) - else: - for opt in options: - if opt._is_legacy_option or opt._is_compile_state: - cache_key = opt._generate_path_cache_key(cache_path) - if cache_key is False: - self.spoil(full=True) - elif cache_key is not None: - key += cache_key + for opt in options: + if opt._is_legacy_option or opt._is_compile_state: + ck = opt._generate_cache_key() + if ck is None: + self.spoil(full=True) + else: + key += ck[0] self.add_criteria( lambda q: q._with_current_path(effective_path).options(*options), diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 9782d92b7..e569c0603 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -715,15 +715,6 @@ class LoaderOption(ORMOption): def process_compile_state(self, compile_state): """Apply a modification to a given :class:`.CompileState`.""" - def _generate_path_cache_key(self, path): - """Used by the "baked lazy loader" to see if this option can be cached. - - .. deprecated:: 2.0 this method is to suit the baked extension which - is itself not part of 2.0. - - """ - return False - class UserDefinedOption(ORMOption): """Base class for a user-defined option that can be consumed from the @@ -782,25 +773,6 @@ class MapperOption(ORMOption): self.process_query(query) - def _generate_path_cache_key(self, path): - """Used by the "baked lazy loader" to see if this option can be cached. - - By default, this method returns the value ``False``, which means - the :class:`.BakedQuery` generated by the lazy loader will - not cache the SQL when this :class:`.MapperOption` is present. - This is the safest option and ensures both that the option is - invoked every time, and also that the cache isn't filled up with - an unlimited number of :class:`_query.Query` objects for an unlimited - number of :class:`.MapperOption` objects. - - For caching support it is recommended to use the - :class:`.UserDefinedOption` class in conjunction with - the :meth:`.Session.do_orm_execute` method so that statements may - be modified before they are cached. - - """ - return False - class LoaderStrategy(object): """Describe the loading behavior of a StrategizedProperty object. diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py index a059c67ac..3cc1b97f9 100644 --- a/lib/sqlalchemy/orm/strategy_options.py +++ b/lib/sqlalchemy/orm/strategy_options.py @@ -114,76 +114,6 @@ class Load(Generative, LoaderOption): serialized.append(loader_path + (obj,)) return serialized - def _generate_path_cache_key(self, path): - if path.path[0].is_aliased_class: - return False - - serialized = [] - for (key, loader_path), obj in self.context.items(): - if key != "loader": - continue - - for local_elem, obj_elem in zip(self.path.path, loader_path): - if local_elem is not obj_elem: - break - else: - endpoint = obj._of_type or obj.path.path[-1] - chopped = self._chop_path(loader_path, path) - - if ( - # means loader_path and path are unrelated, - # this does not need to be part of a cache key - chopped - is None - ) or ( - # means no additional path with loader_path + path - # and the endpoint isn't using of_type so isn't modified - # into an alias or other unsafe entity - not chopped - and not obj._of_type - ): - continue - - serialized_path = [] - - for token in chopped: - if isinstance(token, util.string_types): - serialized_path.append(token) - elif token.is_aliased_class: - return False - elif token.is_property: - serialized_path.append(token.key) - else: - assert token.is_mapper - serialized_path.append(token.class_) - - if not serialized_path or endpoint != serialized_path[-1]: - if endpoint.is_mapper: - serialized_path.append(endpoint.class_) - elif endpoint.is_aliased_class: - return False - - serialized.append( - ( - tuple(serialized_path) - + (obj.strategy or ()) - + ( - tuple( - [ - (key, obj.local_opts[key]) - for key in sorted(obj.local_opts) - ] - ) - if obj.local_opts - else () - ) - ) - ) - if not serialized: - return None - else: - return tuple(serialized) - def _generate(self): cloned = super(Load, self)._generate() cloned.local_opts = {} @@ -588,25 +518,6 @@ class _UnboundLoad(Load): _is_chain_link = False - def _generate_path_cache_key(self, path): - serialized = () - for val in self._to_bind: - for local_elem, val_elem in zip(self.path, val.path): - if local_elem is not val_elem: - break - else: - opt = val._bind_loader([path.path[0]], None, None, False) - if opt: - c_key = opt._generate_path_cache_key(path) - if c_key is False: - return False - elif c_key: - serialized += c_key - if not serialized: - return None - else: - return serialized - def _set_path_strategy(self): self._to_bind.append(self) diff --git a/test/aaa_profiling/test_orm.py b/test/aaa_profiling/test_orm.py index 13e92f5c4..850159323 100644 --- a/test/aaa_profiling/test_orm.py +++ b/test/aaa_profiling/test_orm.py @@ -1,6 +1,5 @@ from sqlalchemy import and_ from sqlalchemy import ForeignKey -from sqlalchemy import inspect from sqlalchemy import Integer from sqlalchemy import join from sqlalchemy import String @@ -1104,46 +1103,6 @@ class BranchedOptionTest(NoCache, fixtures.MappedTest): configure_mappers() - def test_generate_path_cache_key_unbound_branching(self): - A, B, C, D, E, F, G = self.classes("A", "B", "C", "D", "E", "F", "G") - - base = joinedload(A.bs) - opts = [ - base.joinedload(B.cs), - base.joinedload(B.ds), - base.joinedload(B.es), - base.joinedload(B.fs), - ] - - cache_path = inspect(A)._path_registry - - @profiling.function_call_count(warmup=1) - def go(): - for opt in opts: - opt._generate_path_cache_key(cache_path) - - go() - - def test_generate_path_cache_key_bound_branching(self): - A, B, C, D, E, F, G = self.classes("A", "B", "C", "D", "E", "F", "G") - - base = Load(A).joinedload(A.bs) - opts = [ - base.joinedload(B.cs), - base.joinedload(B.ds), - base.joinedload(B.es), - base.joinedload(B.fs), - ] - - cache_path = inspect(A)._path_registry - - @profiling.function_call_count(warmup=1) - def go(): - for opt in opts: - opt._generate_path_cache_key(cache_path) - - go() - def test_query_opts_unbound_branching(self): A, B, C, D, E, F, G = self.classes("A", "B", "C", "D", "E", "F", "G") diff --git a/test/ext/test_baked.py b/test/ext/test_baked.py index 5bd380bb8..15919765c 100644 --- a/test/ext/test_baked.py +++ b/test/ext/test_baked.py @@ -1179,7 +1179,7 @@ class LazyLoaderTest(testing.AssertsCompiledSQL, BakedTest): u1.addresses eq_(m1.mock_calls, [mock.call(User), mock.call(Address)]) - def test_unsafe_unbound_option_cancels_bake(self): + def test_aliased_unbound_are_now_safe_to_cache(self): User, Address, Dingaling = self._o2m_twolevel_fixture(lazy="joined") class SubDingaling(Dingaling): @@ -1206,9 +1206,9 @@ class LazyLoaderTest(testing.AssertsCompiledSQL, BakedTest): ad.dingalings l2 = len(lru) eq_(l1, 0) - eq_(l2, 0) + eq_(l2, 2) - def test_unsafe_bound_option_cancels_bake(self): + def test_aliased_bound_are_now_safe_to_cache(self): User, Address, Dingaling = self._o2m_twolevel_fixture(lazy="joined") class SubDingaling(Dingaling): @@ -1237,7 +1237,7 @@ class LazyLoaderTest(testing.AssertsCompiledSQL, BakedTest): ad.dingalings l2 = len(lru) eq_(l1, 0) - eq_(l2, 0) + eq_(l2, 2) def test_safe_unbound_option_allows_bake(self): User, Address, Dingaling = self._o2m_twolevel_fixture(lazy="joined") @@ -1307,6 +1307,7 @@ class LazyLoaderTest(testing.AssertsCompiledSQL, BakedTest): propagate_to_loaders=True, _gen_cache_key=lambda *args: ("hi",), _generate_path_cache_key=lambda path: ("hi",), + _generate_cache_key=lambda *args: (("hi",), []), ) u1 = sess.query(User).options(mock_opt).first() diff --git a/test/orm/test_options.py b/test/orm/test_options.py index 034e940d9..74a8677bf 100644 --- a/test/orm/test_options.py +++ b/test/orm/test_options.py @@ -13,7 +13,6 @@ from sqlalchemy.orm import defaultload from sqlalchemy.orm import defer from sqlalchemy.orm import exc as orm_exc from sqlalchemy.orm import joinedload -from sqlalchemy.orm import lazyload from sqlalchemy.orm import Load from sqlalchemy.orm import load_only from sqlalchemy.orm import mapper @@ -1841,802 +1840,3 @@ class SubOptionsTest(PathTest, QueryTest): joinedload(User.orders).options, Load(Order).joinedload(Order.items), ) - - -class PathedCacheKeyTest(PathTest, QueryTest): - - run_create_tables = False - run_inserts = None - run_deletes = None - - def test_unbound_cache_key_included_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = joinedload(User.orders).joinedload(Order.items) - eq_( - opt._generate_path_cache_key(query_path), - (((Order, "items", Item, ("lazy", "joined")),)), - ) - - def test_unbound_cache_key_included_safe_multipath(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - base = joinedload(User.orders) - opt1 = base.joinedload(Order.items) - opt2 = base.joinedload(Order.address) - - eq_( - opt1._generate_path_cache_key(query_path), - (((Order, "items", Item, ("lazy", "joined")),)), - ) - - eq_( - opt2._generate_path_cache_key(query_path), - (((Order, "address", Address, ("lazy", "joined")),)), - ) - - def test_bound_cache_key_included_safe_multipath(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - base = Load(User).joinedload(User.orders) - opt1 = base.joinedload(Order.items) - opt2 = base.joinedload(Order.address) - - eq_( - opt1._generate_path_cache_key(query_path), - (((Order, "items", Item, ("lazy", "joined")),)), - ) - - eq_( - opt2._generate_path_cache_key(query_path), - (((Order, "address", Address, ("lazy", "joined")),)), - ) - - def test_bound_cache_key_included_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = Load(User).joinedload(User.orders).joinedload(Order.items) - eq_( - opt._generate_path_cache_key(query_path), - (((Order, "items", Item, ("lazy", "joined")),)), - ) - - def test_unbound_cache_key_excluded_on_other(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = joinedload(User.orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_bound_cache_key_excluded_on_other(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = Load(User).joinedload(User.orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_unbound_cache_key_excluded_on_aliased(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - # query of: - # - # query(User).options( - # joinedload(aliased(User).orders).joinedload(Order.items)) - # - # we are lazy loading Order objects from User.orders - # the path excludes our option so cache key should - # be None - - query_path = self._make_path_registry([User, "orders"]) - - opt = joinedload(aliased(User).orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_bound_cache_key_wildcard_one(self): - # do not change this test, it is testing - # a specific condition in Load._chop_path(). - User, Address = self.classes("User", "Address") - - query_path = self._make_path_registry([User, "addresses"]) - - opt = Load(User).lazyload("*") - eq_(opt._generate_path_cache_key(query_path), None) - - def test_unbound_cache_key_wildcard_one(self): - User, Address = self.classes("User", "Address") - - query_path = self._make_path_registry([User, "addresses"]) - - opt = lazyload("*") - eq_( - opt._generate_path_cache_key(query_path), - (("relationship:_sa_default", ("lazy", "select")),), - ) - - def test_bound_cache_key_wildcard_two(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([User]) - - opt = Load(User).lazyload("orders").lazyload("*") - eq_( - opt._generate_path_cache_key(query_path), - ( - ("orders", Order, ("lazy", "select")), - ("orders", Order, "relationship:*", ("lazy", "select")), - ), - ) - - def test_unbound_cache_key_wildcard_two(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([User]) - - opt = lazyload("orders").lazyload("*") - eq_( - opt._generate_path_cache_key(query_path), - ( - ("orders", Order, ("lazy", "select")), - ("orders", Order, "relationship:*", ("lazy", "select")), - ), - ) - - def test_unbound_cache_key_of_type_subclass_relationship(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([Order, "items", Item]) - - opt = subqueryload(Order.items.of_type(SubItem)).subqueryload( - SubItem.extra_keywords - ) - - eq_( - opt._generate_path_cache_key(query_path), - ( - (SubItem, ("lazy", "subquery")), - ("extra_keywords", Keyword, ("lazy", "subquery")), - ), - ) - - def test_unbound_cache_key_of_type_subclass_relationship_stringattr(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([Order, "items", Item]) - - opt = subqueryload(Order.items.of_type(SubItem)).subqueryload( - "extra_keywords" - ) - - eq_( - opt._generate_path_cache_key(query_path), - ( - (SubItem, ("lazy", "subquery")), - ("extra_keywords", Keyword, ("lazy", "subquery")), - ), - ) - - def test_bound_cache_key_of_type_subclass_relationship(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([Order, "items", Item]) - - opt = ( - Load(Order) - .subqueryload(Order.items.of_type(SubItem)) - .subqueryload(SubItem.extra_keywords) - ) - - eq_( - opt._generate_path_cache_key(query_path), - ( - (SubItem, ("lazy", "subquery")), - ("extra_keywords", Keyword, ("lazy", "subquery")), - ), - ) - - def test_bound_cache_key_of_type_subclass_string_relationship(self): - User, Address, Order, Item, SubItem, Keyword = self.classes( - "User", "Address", "Order", "Item", "SubItem", "Keyword" - ) - - query_path = self._make_path_registry([Order, "items", Item]) - - opt = ( - Load(Order) - .subqueryload(Order.items.of_type(SubItem)) - .subqueryload("extra_keywords") - ) - - eq_( - opt._generate_path_cache_key(query_path), - ( - (SubItem, ("lazy", "subquery")), - ("extra_keywords", Keyword, ("lazy", "subquery")), - ), - ) - - def test_unbound_cache_key_excluded_of_type_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - # query of: - # - # query(User).options( - # subqueryload(User.orders). - # subqueryload(Order.items.of_type(SubItem))) - # - # - # we are lazy loading Address objects from User.addresses - # the path excludes our option so cache key should - # be None - - query_path = self._make_path_registry([User, "addresses"]) - - opt = subqueryload(User.orders).subqueryload( - Order.items.of_type(SubItem) - ) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_unbound_cache_key_excluded_of_type_unsafe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - # query of: - # - # query(User).options( - # subqueryload(User.orders). - # subqueryload(Order.items.of_type(aliased(SubItem)))) - # - # - # we are lazy loading Address objects from User.addresses - # the path excludes our option so cache key should - # be None - - query_path = self._make_path_registry([User, "addresses"]) - - opt = subqueryload(User.orders).subqueryload( - Order.items.of_type(aliased(SubItem)) - ) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_bound_cache_key_excluded_of_type_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - # query of: - # - # query(User).options( - # subqueryload(User.orders). - # subqueryload(Order.items.of_type(SubItem))) - # - # - # we are lazy loading Address objects from User.addresses - # the path excludes our option so cache key should - # be None - - query_path = self._make_path_registry([User, "addresses"]) - - opt = ( - Load(User) - .subqueryload(User.orders) - .subqueryload(Order.items.of_type(SubItem)) - ) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_bound_cache_key_excluded_of_type_unsafe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - # query of: - # - # query(User).options( - # subqueryload(User.orders). - # subqueryload(Order.items.of_type(aliased(SubItem)))) - # - # - # we are lazy loading Address objects from User.addresses - # the path excludes our option so cache key should - # be None - - query_path = self._make_path_registry([User, "addresses"]) - - opt = ( - Load(User) - .subqueryload(User.orders) - .subqueryload(Order.items.of_type(aliased(SubItem))) - ) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_unbound_cache_key_included_of_type_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = joinedload(User.orders).joinedload(Order.items.of_type(SubItem)) - eq_( - opt._generate_path_cache_key(query_path), - ((Order, "items", SubItem, ("lazy", "joined")),), - ) - - def test_bound_cache_key_included_of_type_safe(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = ( - Load(User) - .joinedload(User.orders) - .joinedload(Order.items.of_type(SubItem)) - ) - - eq_( - opt._generate_path_cache_key(query_path), - ((Order, "items", SubItem, ("lazy", "joined")),), - ) - - def test_unbound_cache_key_included_unsafe_option_one(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = joinedload(User.orders).joinedload( - Order.items.of_type(aliased(SubItem)) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_unbound_cache_key_included_unsafe_option_two(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders", Order]) - - opt = joinedload(User.orders).joinedload( - Order.items.of_type(aliased(SubItem)) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_unbound_cache_key_included_unsafe_option_three(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders", Order, "items"]) - - opt = joinedload(User.orders).joinedload( - Order.items.of_type(aliased(SubItem)) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_unbound_cache_key_included_unsafe_query(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - au = aliased(User) - query_path = self._make_path_registry([inspect(au), "orders"]) - - opt = joinedload(au.orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_unbound_cache_key_included_safe_w_deferred(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = ( - joinedload(User.addresses) - .defer(Address.email_address) - .defer(Address.user_id) - ) - eq_( - opt._generate_path_cache_key(query_path), - ( - ( - Address, - "email_address", - ("deferred", True), - ("instrument", True), - ), - (Address, "user_id", ("deferred", True), ("instrument", True)), - ), - ) - - def test_unbound_cache_key_included_safe_w_deferred_multipath(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - base = joinedload(User.orders) - opt1 = base.joinedload(Order.items) - opt2 = ( - base.joinedload(Order.address) - .defer(Address.email_address) - .defer(Address.user_id) - ) - - eq_( - opt1._generate_path_cache_key(query_path), - ((Order, "items", Item, ("lazy", "joined")),), - ) - - eq_( - opt2._generate_path_cache_key(query_path), - ( - (Order, "address", Address, ("lazy", "joined")), - ( - Order, - "address", - Address, - "email_address", - ("deferred", True), - ("instrument", True), - ), - ( - Order, - "address", - Address, - "user_id", - ("deferred", True), - ("instrument", True), - ), - ), - ) - - def test_bound_cache_key_included_safe_w_deferred(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = ( - Load(User) - .joinedload(User.addresses) - .defer(Address.email_address) - .defer(Address.user_id) - ) - eq_( - opt._generate_path_cache_key(query_path), - ( - ( - Address, - "email_address", - ("deferred", True), - ("instrument", True), - ), - (Address, "user_id", ("deferred", True), ("instrument", True)), - ), - ) - - def test_bound_cache_key_included_safe_w_deferred_multipath(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - base = Load(User).joinedload(User.orders) - opt1 = base.joinedload(Order.items) - opt2 = ( - base.joinedload(Order.address) - .defer(Address.email_address) - .defer(Address.user_id) - ) - - eq_( - opt1._generate_path_cache_key(query_path), - ((Order, "items", Item, ("lazy", "joined")),), - ) - - eq_( - opt2._generate_path_cache_key(query_path), - ( - (Order, "address", Address, ("lazy", "joined")), - ( - Order, - "address", - Address, - "email_address", - ("deferred", True), - ("instrument", True), - ), - ( - Order, - "address", - Address, - "user_id", - ("deferred", True), - ("instrument", True), - ), - ), - ) - - def test_unbound_cache_key_included_safe_w_option(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - opt = ( - defaultload("orders") - .joinedload("items", innerjoin=True) - .defer("description") - ) - query_path = self._make_path_registry([User, "orders"]) - - eq_( - opt._generate_path_cache_key(query_path), - ( - ( - Order, - "items", - Item, - ("lazy", "joined"), - ("innerjoin", True), - ), - ( - Order, - "items", - Item, - "description", - ("deferred", True), - ("instrument", True), - ), - ), - ) - - def test_bound_cache_key_excluded_on_aliased(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - au = aliased(User) - opt = Load(au).joinedload(au.orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), None) - - def test_bound_cache_key_included_unsafe_option_one(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders"]) - - opt = ( - Load(User) - .joinedload(User.orders) - .joinedload(Order.items.of_type(aliased(SubItem))) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_bound_cache_key_included_unsafe_option_two(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders", Order]) - - opt = ( - Load(User) - .joinedload(User.orders) - .joinedload(Order.items.of_type(aliased(SubItem))) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_bound_cache_key_included_unsafe_option_three(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "orders", Order, "items"]) - - opt = ( - Load(User) - .joinedload(User.orders) - .joinedload(Order.items.of_type(aliased(SubItem))) - ) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_bound_cache_key_included_unsafe_query(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - au = aliased(User) - query_path = self._make_path_registry([inspect(au), "orders"]) - - opt = Load(au).joinedload(au.orders).joinedload(Order.items) - eq_(opt._generate_path_cache_key(query_path), False) - - def test_bound_cache_key_included_safe_w_option(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - opt = ( - Load(User) - .defaultload("orders") - .joinedload("items", innerjoin=True) - .defer("description") - ) - query_path = self._make_path_registry([User, "orders"]) - - eq_( - opt._generate_path_cache_key(query_path), - ( - ( - Order, - "items", - Item, - ("lazy", "joined"), - ("innerjoin", True), - ), - ( - Order, - "items", - Item, - "description", - ("deferred", True), - ("instrument", True), - ), - ), - ) - - def test_unbound_cache_key_included_safe_w_loadonly_strs(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = defaultload(User.addresses).load_only("id", "email_address") - eq_( - opt._generate_path_cache_key(query_path), - ( - (Address, "id", ("deferred", False), ("instrument", True)), - ( - Address, - "email_address", - ("deferred", False), - ("instrument", True), - ), - ( - Address, - "column:*", - ("deferred", True), - ("instrument", True), - ("undefer_pks", True), - ), - ), - ) - - def test_unbound_cache_key_included_safe_w_loadonly_props(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = defaultload(User.addresses).load_only( - Address.id, Address.email_address - ) - eq_( - opt._generate_path_cache_key(query_path), - ( - (Address, "id", ("deferred", False), ("instrument", True)), - ( - Address, - "email_address", - ("deferred", False), - ("instrument", True), - ), - ( - Address, - "column:*", - ("deferred", True), - ("instrument", True), - ("undefer_pks", True), - ), - ), - ) - - def test_bound_cache_key_included_safe_w_loadonly(self): - User, Address, Order, Item, SubItem = self.classes( - "User", "Address", "Order", "Item", "SubItem" - ) - - query_path = self._make_path_registry([User, "addresses"]) - - opt = ( - Load(User) - .defaultload(User.addresses) - .load_only("id", "email_address") - ) - eq_( - opt._generate_path_cache_key(query_path), - ( - (Address, "id", ("deferred", False), ("instrument", True)), - ( - Address, - "email_address", - ("deferred", False), - ("instrument", True), - ), - ( - Address, - "column:*", - ("deferred", True), - ("instrument", True), - ("undefer_pks", True), - ), - ), - ) - - def test_unbound_cache_key_undefer_group(self): - User, Address = self.classes("User", "Address") - - query_path = self._make_path_registry([User, "addresses"]) - - opt = defaultload(User.addresses).undefer_group("xyz") - - eq_( - opt._generate_path_cache_key(query_path), - ((Address, "column:*", ("undefer_group_xyz", True)),), - ) - - def test_bound_cache_key_undefer_group(self): - User, Address = self.classes("User", "Address") - - query_path = self._make_path_registry([User, "addresses"]) - - opt = Load(User).defaultload(User.addresses).undefer_group("xyz") - - eq_( - opt._generate_path_cache_key(query_path), - ((Address, "column:*", ("undefer_group_xyz", True)),), - ) diff --git a/test/profiles.txt b/test/profiles.txt index 09f226804..79097197f 100644 --- a/test/profiles.txt +++ b/test/profiles.txt @@ -240,20 +240,6 @@ test.aaa_profiling.test_orm.AttributeOverheadTest.test_collection_append_remove test.aaa_profiling.test_orm.AttributeOverheadTest.test_collection_append_remove 3.8_sqlite_pysqlite_dbapiunicode_cextensions 5828 test.aaa_profiling.test_orm.AttributeOverheadTest.test_collection_append_remove 3.8_sqlite_pysqlite_dbapiunicode_nocextensions 5828 -# TEST: test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_bound_branching - -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_bound_branching 2.7_sqlite_pysqlite_dbapiunicode_cextensions 104 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_bound_branching 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 104 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_bound_branching 3.8_sqlite_pysqlite_dbapiunicode_cextensions 81 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_bound_branching 3.8_sqlite_pysqlite_dbapiunicode_nocextensions 81 - -# TEST: test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_unbound_branching - -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_unbound_branching 2.7_sqlite_pysqlite_dbapiunicode_cextensions 588 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_unbound_branching 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 588 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_unbound_branching 3.8_sqlite_pysqlite_dbapiunicode_cextensions 561 -test.aaa_profiling.test_orm.BranchedOptionTest.test_generate_path_cache_key_unbound_branching 3.8_sqlite_pysqlite_dbapiunicode_nocextensions 561 - # TEST: test.aaa_profiling.test_orm.BranchedOptionTest.test_query_opts_key_bound_branching test.aaa_profiling.test_orm.BranchedOptionTest.test_query_opts_key_bound_branching 2.7_sqlite_pysqlite_dbapiunicode_cextensions 61 @@ -368,10 +354,10 @@ test.aaa_profiling.test_orm.QueryTest.test_query_cols 3.8_sqlite_pysqlite_dbapiu # TEST: test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results -test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 2.7_sqlite_pysqlite_dbapiunicode_cextensions 172835 -test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 189061 -test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 3.8_sqlite_pysqlite_dbapiunicode_cextensions 177706 -test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 3.8_sqlite_pysqlite_dbapiunicode_nocextensions 195128 +test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 2.7_sqlite_pysqlite_dbapiunicode_cextensions 152251 +test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 2.7_sqlite_pysqlite_dbapiunicode_nocextensions 168676 +test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 3.8_sqlite_pysqlite_dbapiunicode_cextensions 159629 +test.aaa_profiling.test_orm.SelectInEagerLoadTest.test_round_trip_results 3.8_sqlite_pysqlite_dbapiunicode_nocextensions 177451 # TEST: test.aaa_profiling.test_orm.SessionTest.test_expire_lots |