diff options
Diffstat (limited to 'lib/sqlalchemy/orm/loading.py')
-rw-r--r-- | lib/sqlalchemy/orm/loading.py | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 617f027d9..193980e6c 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -28,6 +28,7 @@ from .util import aliased from .util import state_str from .. import exc as sa_exc from .. import util +from ..engine import result_tuple from ..sql import util as sql_util @@ -56,7 +57,7 @@ def instances(query, cursor, context): ) try: - (process, labels) = list( + (process, labels, extra) = list( zip( *[ query_entity.row_processor(query, context, cursor) @@ -66,7 +67,7 @@ def instances(query, cursor, context): ) if not single_entity: - keyed_tuple = util.lightweight_named_tuple("result", labels) + keyed_tuple = result_tuple(labels, extra) while True: context.partials = {} @@ -138,7 +139,9 @@ def merge_result(querylib, query, iterator, load=True): ] result = [] keys = [ent._label_name for ent in query._entities] - keyed_tuple = util.lightweight_named_tuple("result", keys) + keyed_tuple = result_tuple( + keys, [ent.entities for ent in query._entities] + ) for row in iterator: newrow = list(row) for i in mapped_entities: @@ -190,7 +193,6 @@ def load_on_ident( query, key, refresh_state=None, with_for_update=None, only_load_props=None ): """Load the given identity key from the database.""" - if key is not None: ident = key[1] identity_token = key[2] @@ -452,10 +454,19 @@ def _instance_processor( instance_state = attributes.instance_state instance_dict = attributes.instance_dict session_id = context.session.hash_key - version_check = context.version_check runid = context.runid identity_token = context.identity_token + version_check = context.version_check + if version_check: + version_id_col = mapper.version_id_col + if version_id_col is not None: + if adapter: + version_id_col = adapter.columns[version_id_col] + version_id_getter = result._getter(version_id_col) + else: + version_id_getter = None + if not refresh_state and _polymorphic_from is not None: key = ("loader", path.path) if key in context.attributes and context.attributes[key].strategy == ( @@ -539,8 +550,10 @@ def _instance_processor( currentload = not isnew loaded_instance = False - if version_check and not currentload: - _validate_version_id(mapper, state, dict_, row, adapter) + if version_check and version_id_getter and not currentload: + _validate_version_id( + mapper, state, dict_, row, version_id_getter + ) else: # create a new instance @@ -667,7 +680,7 @@ def _instance_processor( def ensure_no_pk(row): identitykey = ( identity_class, - tuple([row[column] for column in pk_cols]), + tuple_getter(row), identity_token, ) if not is_not_primary_key(identitykey[1]): @@ -812,20 +825,11 @@ def _populate_partial( return to_load -def _validate_version_id(mapper, state, dict_, row, adapter): +def _validate_version_id(mapper, state, dict_, row, getter): - version_id_col = mapper.version_id_col - - if version_id_col is None: - return - - if adapter: - version_id_col = adapter.columns[version_id_col] - - if ( - mapper._get_state_attr_by_column(state, dict_, mapper.version_id_col) - != row[version_id_col] - ): + if mapper._get_state_attr_by_column( + state, dict_, mapper.version_id_col + ) != getter(row): raise orm_exc.StaleDataError( "Instance '%s' has version id '%s' which " "does not match database-loaded version id '%s'." @@ -834,7 +838,7 @@ def _validate_version_id(mapper, state, dict_, row, adapter): mapper._get_state_attr_by_column( state, dict_, mapper.version_id_col ), - row[version_id_col], + getter(row), ) ) |