summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/build/changelog/unreleased_12/4298.rst7
-rw-r--r--lib/sqlalchemy/orm/strategy_options.py6
-rw-r--r--test/orm/test_options.py52
3 files changed, 62 insertions, 3 deletions
diff --git a/doc/build/changelog/unreleased_12/4298.rst b/doc/build/changelog/unreleased_12/4298.rst
new file mode 100644
index 000000000..8066ccdd0
--- /dev/null
+++ b/doc/build/changelog/unreleased_12/4298.rst
@@ -0,0 +1,7 @@
+.. change::
+ :tags: bug, orm
+ :tickets: 4298
+
+ Fixed regression in 1.2.9 due to :ticket:`4287` where using a
+ :class::`.Load` option in conjunction with a string wildcard would result
+ in a TypeError.
diff --git a/lib/sqlalchemy/orm/strategy_options.py b/lib/sqlalchemy/orm/strategy_options.py
index 90d14075c..af9bd71b6 100644
--- a/lib/sqlalchemy/orm/strategy_options.py
+++ b/lib/sqlalchemy/orm/strategy_options.py
@@ -13,7 +13,8 @@ from .attributes import QueryableAttribute
from .. import util
from ..sql.base import _generative, Generative
from .. import exc as sa_exc, inspect
-from .base import _is_aliased_class, _class_to_mapper, _is_mapped_class
+from .base import _is_aliased_class, _class_to_mapper, _is_mapped_class, \
+ InspectionAttr
from . import util as orm_util
from .path_registry import PathRegistry, TokenRegistry, \
_WILDCARD_TOKEN, _DEFAULT_TOKEN
@@ -385,7 +386,8 @@ class Load(Generative, MapperOption):
if c_token is p_token:
continue
- elif c_token.is_mapper and p_token.is_mapper and \
+ elif isinstance(c_token, InspectionAttr) and \
+ c_token.is_mapper and p_token.is_mapper and \
c_token.isa(p_token):
continue
else:
diff --git a/test/orm/test_options.py b/test/orm/test_options.py
index 3c1f6527d..e94b9e6b6 100644
--- a/test/orm/test_options.py
+++ b/test/orm/test_options.py
@@ -2,7 +2,7 @@ from sqlalchemy import inspect
from sqlalchemy.orm import attributes, mapper, relationship, backref, \
configure_mappers, create_session, synonym, Session, class_mapper, \
aliased, column_property, joinedload_all, joinedload, Query,\
- util as orm_util, Load, defer, defaultload
+ util as orm_util, Load, defer, defaultload, lazyload
from sqlalchemy.orm.query import QueryContext
from sqlalchemy.orm import strategy_options
import sqlalchemy as sa
@@ -1228,6 +1228,56 @@ class CacheKeyTest(PathTest, QueryTest):
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_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_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_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_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")