diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-07-14 11:51:11 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-07-14 11:51:11 -0400 |
commit | 3eaedb38d306095c683900e7e4625be7f7bc91d2 (patch) | |
tree | 1bb7f5ed594ff7c199761bc6ad8e87248c6070cc /lib/sqlalchemy/orm/loading.py | |
parent | 0dde519fe172cf3ac7241cbb1ab93b35beaf6d6a (diff) | |
download | sqlalchemy-3eaedb38d306095c683900e7e4625be7f7bc91d2.tar.gz |
- move load_scalar_attributes out to loading.py
Diffstat (limited to 'lib/sqlalchemy/orm/loading.py')
-rw-r--r-- | lib/sqlalchemy/orm/loading.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 987d47cea..41b82d8d1 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -18,6 +18,8 @@ from . import attributes, exc as orm_exc, state as statelib from .interfaces import EXT_CONTINUE from ..sql import util as sql_util from .util import _none_set, state_str +from .. import exc as sa_exc +sessionlib = util.importlater("sqlalchemy.orm", "session") _new_runid = util.counter() @@ -534,3 +536,66 @@ def _configure_subclass_mapper(mapper, context, path, adapter): adapter, polymorphic_from=mapper) return configure_subclass_mapper + +def load_scalar_attributes(mapper, state, attribute_names): + """initiate a column-based attribute refresh operation.""" + + #assert mapper is _state_mapper(state) + session = sessionlib._state_session(state) + if not session: + raise orm_exc.DetachedInstanceError( + "Instance %s is not bound to a Session; " + "attribute refresh operation cannot proceed" % + (state_str(state))) + + has_key = bool(state.key) + + result = False + + if mapper.inherits and not mapper.concrete: + statement = mapper._optimized_get_statement(state, attribute_names) + if statement is not None: + result = load_on_ident( + session.query(mapper).from_statement(statement), + None, + only_load_props=attribute_names, + refresh_state=state + ) + + if result is False: + if has_key: + identity_key = state.key + else: + # this codepath is rare - only valid when inside a flush, and the + # object is becoming persistent but hasn't yet been assigned + # an identity_key. + # check here to ensure we have the attrs we need. + pk_attrs = [mapper._columntoproperty[col].key + for col in mapper.primary_key] + if state.expired_attributes.intersection(pk_attrs): + raise sa_exc.InvalidRequestError( + "Instance %s cannot be refreshed - it's not " + " persistent and does not " + "contain a full primary key." % state_str(state)) + identity_key = mapper._identity_key_from_state(state) + + if (_none_set.issubset(identity_key) and \ + not mapper.allow_partial_pks) or \ + _none_set.issuperset(identity_key): + util.warn("Instance %s to be refreshed doesn't " + "contain a full primary key - can't be refreshed " + "(and shouldn't be expired, either)." + % state_str(state)) + return + + result = load_on_ident( + session.query(mapper), + identity_key, + refresh_state=state, + only_load_props=attribute_names) + + # if instance is pending, a refresh operation + # may not complete (even if PK attributes are assigned) + if has_key and result is None: + raise orm_exc.ObjectDeletedError(state) + |