Skip to content

Commit 366e88e

Browse files
committed
Revert 903b188
This was accidentally pushed just now. Change-Id: I4da4151c4a81e5cf72146f8dcab3537301ccaae9
1 parent 6b3513f commit 366e88e

3 files changed

Lines changed: 77 additions & 90 deletions

File tree

lib/sqlalchemy/ext/baked.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ def __str__(self):
383383
return str(self._as_query())
384384

385385
def __iter__(self):
386-
return self._iter().__iter__()
386+
return iter(self._iter())
387387

388388
def _iter(self):
389389
bq = self.bq
@@ -463,23 +463,36 @@ def first(self):
463463
Equivalent to :meth:`_query.Query.first`.
464464
465465
"""
466-
467466
bq = self.bq.with_criteria(lambda q: q.slice(0, 1))
468-
return (
467+
ret = list(
469468
bq.for_session(self.session)
470469
.params(self._params)
471470
._using_post_criteria(self._post_criteria)
472-
._iter()
473-
.first()
474471
)
472+
if len(ret) > 0:
473+
return ret[0]
474+
else:
475+
return None
475476

476477
def one(self):
477478
"""Return exactly one result or raise an exception.
478479
479480
Equivalent to :meth:`_query.Query.one`.
480481
481482
"""
482-
return self._iter().one()
483+
try:
484+
ret = self.one_or_none()
485+
except orm_exc.MultipleResultsFound as err:
486+
util.raise_(
487+
orm_exc.MultipleResultsFound(
488+
"Multiple rows were found for one()"
489+
),
490+
replace_context=err,
491+
)
492+
else:
493+
if ret is None:
494+
raise orm_exc.NoResultFound("No row was found for one()")
495+
return ret
483496

484497
def one_or_none(self):
485498
"""Return one or zero results, or raise an exception for multiple
@@ -490,7 +503,17 @@ def one_or_none(self):
490503
.. versionadded:: 1.0.9
491504
492505
"""
493-
return self._iter().one_or_none()
506+
ret = list(self)
507+
508+
l = len(ret)
509+
if l == 1:
510+
return ret[0]
511+
elif l == 0:
512+
return None
513+
else:
514+
raise orm_exc.MultipleResultsFound(
515+
"Multiple rows were found for one_or_none()"
516+
)
494517

495518
def all(self):
496519
"""Return all rows.

lib/sqlalchemy/orm/loading.py

Lines changed: 44 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
"""
1515
from __future__ import absolute_import
1616

17+
import collections
18+
1719
from . import attributes
1820
from . import exc as orm_exc
1921
from . import path_registry
@@ -586,86 +588,48 @@ def _instance_processor(
586588

587589
identity_class = mapper._identity_class
588590

589-
compile_state = context.compile_state
590-
591-
populators = {}
591+
populators = collections.defaultdict(list)
592592

593593
props = mapper._prop_set
594594
if only_load_props is not None:
595595
props = props.intersection(mapper._props[k] for k in only_load_props)
596596

597-
getters = path.get(compile_state.attributes, "getters", None)
598-
if getters is None:
599-
# directives given to us by the ColumnLoader.setup_query()
600-
# methods. Turn these directives into getters against the
601-
# actual result set.
602-
quick_populators = path.get(
603-
context.attributes, "memoized_setups", _none_set
604-
)
605-
cached_populators = {
606-
"new": [],
607-
"expire": [],
608-
"quick": [],
609-
"todo": [],
610-
"delayed": [],
611-
"existing": [],
612-
"eager": [],
613-
}
614-
615-
pk_cols = mapper.primary_key
597+
quick_populators = path.get(
598+
context.attributes, "memoized_setups", _none_set
599+
)
616600

617-
if adapter:
618-
pk_cols = [adapter.columns[c] for c in pk_cols]
619-
getters = {
620-
"populators": cached_populators,
621-
"primary_key_getter": result._tuple_getter(pk_cols),
622-
}
623-
624-
for prop in props:
625-
if prop in quick_populators:
626-
# this is an inlined path just for column-based attributes.
627-
col = quick_populators[prop]
628-
if col is _DEFER_FOR_STATE:
629-
cached_populators["new"].append(
630-
(prop.key, prop._deferred_column_loader)
631-
)
632-
elif col is _SET_DEFERRED_EXPIRED:
633-
# note that in this path, we are no longer
634-
# searching in the result to see if the column might
635-
# be present in some unexpected way.
636-
cached_populators["expire"].append((prop.key, False))
637-
elif col is _RAISE_FOR_STATE:
638-
cached_populators["new"].append(
639-
(prop.key, prop._raise_column_loader)
640-
)
641-
else:
642-
getter = None
643-
if not getter:
644-
getter = result._getter(col, False)
645-
if getter:
646-
cached_populators["quick"].append((prop.key, getter))
647-
else:
648-
# fall back to the ColumnProperty itself, which
649-
# will iterate through all of its columns
650-
# to see if one fits
651-
prop.create_row_processor(
652-
context,
653-
path,
654-
mapper,
655-
result,
656-
adapter,
657-
cached_populators,
658-
)
601+
for prop in props:
602+
if prop in quick_populators:
603+
# this is an inlined path just for column-based attributes.
604+
col = quick_populators[prop]
605+
if col is _DEFER_FOR_STATE:
606+
populators["new"].append(
607+
(prop.key, prop._deferred_column_loader)
608+
)
609+
elif col is _SET_DEFERRED_EXPIRED:
610+
# note that in this path, we are no longer
611+
# searching in the result to see if the column might
612+
# be present in some unexpected way.
613+
populators["expire"].append((prop.key, False))
614+
elif col is _RAISE_FOR_STATE:
615+
populators["new"].append((prop.key, prop._raise_column_loader))
659616
else:
660-
cached_populators["todo"].append(prop)
661-
path.set(compile_state.attributes, "getters", getters)
662-
663-
cached_populators = getters["populators"]
664-
populators = {k: list(v) for k, v in cached_populators.items()}
665-
for prop in cached_populators["todo"]:
666-
prop.create_row_processor(
667-
context, path, mapper, result, adapter, populators
668-
)
617+
getter = None
618+
if not getter:
619+
getter = result._getter(col, False)
620+
if getter:
621+
populators["quick"].append((prop.key, getter))
622+
else:
623+
# fall back to the ColumnProperty itself, which
624+
# will iterate through all of its columns
625+
# to see if one fits
626+
prop.create_row_processor(
627+
context, path, mapper, result, adapter, populators
628+
)
629+
else:
630+
prop.create_row_processor(
631+
context, path, mapper, result, adapter, populators
632+
)
669633

670634
propagated_loader_options = context.propagated_loader_options
671635
load_path = (
@@ -743,7 +707,11 @@ def _instance_processor(
743707
else:
744708
refresh_identity_key = None
745709

746-
primary_key_getter = getters["primary_key_getter"]
710+
pk_cols = mapper.primary_key
711+
712+
if adapter:
713+
pk_cols = [adapter.columns[c] for c in pk_cols]
714+
tuple_getter = result._tuple_getter(pk_cols)
747715

748716
if mapper.allow_partial_pks:
749717
is_not_primary_key = _none_set.issuperset
@@ -764,11 +732,7 @@ def _instance(row):
764732
else:
765733
# look at the row, see if that identity is in the
766734
# session, or we have to create a new one
767-
identitykey = (
768-
identity_class,
769-
primary_key_getter(row),
770-
identity_token,
771-
)
735+
identitykey = (identity_class, tuple_getter(row), identity_token)
772736

773737
instance = session_identity_map.get(identitykey)
774738

@@ -911,7 +875,7 @@ def _instance(row):
911875
def ensure_no_pk(row):
912876
identitykey = (
913877
identity_class,
914-
primary_key_getter(row),
878+
tuple_getter(row),
915879
identity_token,
916880
)
917881
if not is_not_primary_key(identitykey[1]):

test/ext/test_baked.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def test_one_or_none_multiple_result(self):
180180

181181
assert_raises_message(
182182
orm_exc.MultipleResultsFound,
183-
"Multiple rows were found when one or none was required",
183+
"Multiple rows were found for one_or_none()",
184184
bq(Session()).one_or_none,
185185
)
186186

@@ -192,7 +192,7 @@ def test_one_no_result(self):
192192

193193
assert_raises_message(
194194
orm_exc.NoResultFound,
195-
"No row was found when one was required",
195+
"No row was found for one()",
196196
bq(Session()).one,
197197
)
198198

@@ -213,7 +213,7 @@ def test_one_multiple_result(self):
213213

214214
assert_raises_message(
215215
orm_exc.MultipleResultsFound,
216-
"Multiple rows were found when exactly one was required",
216+
"Multiple rows were found for one()",
217217
bq(Session()).one,
218218
)
219219

0 commit comments

Comments
 (0)