From: Mike Bayer Date: Sun, 28 Jun 2020 16:47:32 +0000 (-0400) Subject: Remove _generate_path_cache_key() X-Git-Tag: rel_1_4_0b1~249^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0286dcb23d8f6facb09391b46581d525982c20a0;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Remove _generate_path_cache_key() loader options can now make a deterministic cache key based on the structure they are given, and this accommodates for aliased classes as well so that these cache keys are now "safe". Have baked query call upon the regular cache key method. Change-Id: Iaa2ef4064cfb16146f415ca73080f32003dd830d --- diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index 4f40637c5b..ecbf871e2a 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 9782d92b74..e569c06031 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 a059c67ac2..3cc1b97f99 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 13e92f5c4d..850159323c 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 5bd380bb8c..15919765cb 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 034e940d94..74a8677bf7 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 09f2268042..79097197f0 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