where the parent entity is not fully present.
[ticket:2069]
+ - Fixed bug in query.options() whereby a path
+ applied to a lazyload using string keys could
+ overlap a same named attribute on the wrong
+ entity. Note 0.6 has a more conservative fix
+ to this. [ticket:2098]
+
- sql
- Added a fully descriptive error message for the
case where Column is subclassed and _make_proxy()
l = []
mappers = []
- # _current_path implies we're in a secondary load with an
- # existing path
-
+ # _current_path implies we're in a
+ # secondary load with an existing path
current_path = list(query._current_path)
tokens = deque(self.key)
sub_tokens = token.split(".", 1)
token = sub_tokens[0]
tokens.extendleft(sub_tokens[1:])
+
+ # exhaust current_path before
+ # matching tokens to entities
+ if current_path:
+ if current_path[1] == token:
+ current_path = current_path[2:]
+ continue
+ else:
+ return [], []
+
if not entity:
- if current_path:
- if current_path[1] == token:
- current_path = current_path[2:]
- continue
- entity = self._find_entity_basestring(query,
- token, raiseerr)
+ entity = self._find_entity_basestring(
+ query,
+ token,
+ raiseerr)
path_element = entity.path_entity
mapper = entity.mapper
mappers.append(mapper)
prop = None
elif isinstance(token, PropComparator):
prop = token.property
+
+ # exhaust current_path before
+ # matching tokens to entities
+ if current_path:
+ if current_path[0:2] == \
+ [token.parententity, prop.key]:
+ current_path = current_path[2:]
+ continue
+ else:
+ return [], []
+
if not entity:
- if current_path:
- if current_path[0:2] == [token.parententity,
- prop.key]:
- current_path = current_path[2:]
- continue
- entity = self._find_entity_prop_comparator(query,
- prop.key, token.parententity, raiseerr)
+ entity = self._find_entity_prop_comparator(
+ query,
+ prop.key,
+ token.parententity,
+ raiseerr)
if not entity:
return [], []
path_element = entity.path_entity
mapper = entity.mapper
mappers.append(prop.parent)
else:
- raise sa_exc.ArgumentError('mapper option expects '
- 'string key or list of attributes')
+ raise sa_exc.ArgumentError(
+ "mapper option expects "
+ "string key or list of attributes")
if prop is None:
return [], []
path = build_path(path_element, prop.key, path)
path_element = path_element
if current_path:
+ # ran out of tokens before
+ # current_path was exhausted.
+ assert not tokens
return [], []
+
return l, mappers
((joinedload("orders.items"), ), 10),
((
joinedload(User.orders, ),
- joinedload(User.orders, Order.items),
+ joinedload(User.orders, Order.items),
joinedload(User.orders, Order.items, Item.keywords),
- ), 1),
+ ), 1),
((
joinedload(User.orders, Order.items, Item.keywords),
), 10),
((
- joinedload(User.orders, Order.items),
- joinedload(User.orders, Order.items, Item.keywords),
+ joinedload(User.orders, Order.items),
+ joinedload(User.orders, Order.items, Item.keywords),
), 5),
]:
sess = create_session()
opt = self._option_fixture(User.addresses)
self._assert_path_result(opt, q, [(User, 'addresses')], [User])
+ def test_path_on_entity_but_doesnt_match_currentpath(self):
+ # ensure "current path" is fully consumed before
+ # matching against current entities.
+ # see [ticket:2098]
+ sess = Session()
+ q = sess.query(User)
+ opt = self._option_fixture('email_address', 'id')
+ q = sess.query(Address)._with_current_path([class_mapper(User), 'addresses'])
+ self._assert_path_result(opt, q, [], [])
+
def test_get_path_one_level_with_unrelated(self):
sess = Session()
q = sess.query(Order)