U a@sdZddlmZddlmZddlmZddlmZddlmZddl m Z dd l m Z dd l m Z dd l mZdd l mZd dlmZd dlmZd dlm Z d dlmZd dlmZd dlmZd dlmZd dlm Zd dlmZe ZddZe dd=ddZ e !dde dd>ddZ"dd Z#d!d!d!d!d"e j$e j$fd#d$Z%d!d!d!d!d!d"e j$e j$fd%d&Z&d?d'd(Z'd@d)d*Z(d+d,Z)dAd-d.Z*d/d0Z+d1d2Z,d3d4Z-d5d6Z.d7d8Z/Gd9d:d:e0Z1d;d<Z2d!S)Bzprivate module containing functions used to convert database rows into object instances and associated state. the functions here are called primarily by Query, Mapper, as well as some of the attribute loading strategies. )absolute_import) attributes)exc) path_registry)strategy_options)_DEFER_FOR_STATE)_RAISE_FOR_STATE)_SET_DEFERRED_EXPIRED) _none_set) state_str)future)util) result_tuple)ChunkedIteratorResult) FrozenResult)SimpleResultMetaData)LABEL_STYLE_TABLENAME_PLUS_COLc st_i_j}|j}jj oDszinstances..zCan't use yield_per with eager loaders that require uniquing or row buffering, e.g. joinedload() against collections or subqueryload(). Consider the selectinload() strategy for better flexibility in loading objects.cSstddS)Nz@Can't use the ORM yield_per feature in conjunction with unique()sa_excInvalidRequestError)entryrrr _no_uniqueZszinstances.._no_uniquecsfdd}|S)NcstddS)NzkCan't apply uniqueness to row tuple containing value of type %r; this datatype produces non-hashable valuesrobjdatatyperrgo`s z,instances.._not_hashable..gor)r$r%rr#r _not_hashable_s z instances.._not_hashablecs0g|](}jrn|js$|js$|jr(tndqSN) yield_peruse_id_for_hash_non_hashable_valueZ_null_column_typeidrent)r rrrrjs cs<g|]4}jrn$|js*|jr*|jjn |jr4tndqSr')r(r)r*columntyper+r,)r r&rrrrws)Z_unique_filtersc3s|}i_|r |}|s(qn}rHdfdd|D}nfdd|D}jD]\}}||qd|V|sqqdS)Nrcsg|] }|qSrr)rrowprocrrrsz-instances..chunks..cs"g|]tfddDqS)csg|] }|qSrr)rr2r0rrrsz8instances..chunks...)tuple)r)processr3rrs)partialsZ fetchmanyZ _raw_all_rowspost_load_pathsitemsinvoke)sizer(fetchrowspath post_load)rrr5 single_entityr1rchunkss$  zinstances..chunksZprebuffer_rowsFNcstSr')iter)r:) _prebufferedrrr@s)Zsource_supports_scalarsrawZdynamic_yield_per)filteredZis_single_entitycSstddS)Nz~The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collectionsrr!rrrrequire_uniquesz!instances..require_unique)! _new_runidrunidr7 compile_stateZ_has_mapper_entities load_optionsZ_only_return_tupleslen _entitiesZsupports_single_entitylistzipr(Zloaders_require_bufferingZloaders_require_uniquingrr ExceptionrZ safe_reraisecloseZ_legacy_uniquingrexecution_optionsgetrrZ_is_server_side _attributesuniondictZmulti_row_eager_loadersZ_unique_filter_state) rrrHrDlabelsextraZunique_filtersZ row_metadatar@resultrEr)r r&rBrrr5r?r instances's|                 rXzsqlalchemy.orm.contextTc stjj|r|jj|dd}|j}zd|_fddt|jD}dd|jD}t |dd|jD}g} | D]T} |D]<} | | dk r|j t | | t | | |iid| | <q| || q||| WS||_XdS) azMerge a :class:`_engine.FrozenResult` back into a :class:`_orm.Session`, returning a new :class:`_engine.Result` object with :term:`persistent` objects. See the section :ref:`do_orm_execute_re_executing` for an example. .. seealso:: :ref:`do_orm_execute_re_executing` :meth:`_engine.Result.freeze` :class:`_engine.FrozenResult` Flegacycs g|]\}}t|jr|qSr isinstance _MapperEntityrie querycontextrrrs z'merge_frozen_result..cSsg|] }|jqSrZ _label_namer,rrrrscSsg|] }|jqSrZ_extra_entitiesr,rrrrsNload _recursiveZ_resolve_conflict_map)r preloaded orm_context _autoflushORMSelectCompileState_create_entities_collection autoflush enumeraterKrZ rewrite_rows_mergerinstance_state instance_dictappendZ with_new_rows) session statement frozen_resultrfctxrmmapped_entitieskeys keyed_tuplerWnewrowr_rrarmerge_frozen_results@      r{z2.0zdThe :func:`_orm.merge_result` method is superseded by the :func:`_orm.merge_frozen_result` function.c svtjj|jrt|tr4|}t|j}nd}j j |dd}j }zd_ | ojt |j dk}|rt|j djrfdd|D}nt|}nfd dt|j D}g}d d|j D} t| d d|j D} |D]\} t| } |D]<} | | dk rjt| | t| | iid | | <q|| | q|rZ||WSt|WSW5|_ XdS) z:Merge a result into this :class:`.Query` object's Session.NTrYFrrc s,g|]$}jt|t|iidqS)re)rorrprq)rinstance)rfrsrrr-sz merge_result..cs g|]\}}t|jr|qSrr[r^rarrr:s cSsg|] }|jqSrrcr,rrrr@scSsg|] }|jqSrrdr,rrrrCsre)rrhrirsrjr\rrAdatarkrlrmrJrKr]rLrnrrorrprqrrZ with_data)queryiteratorrfrurvrmr?rWrwrxryr0rzr_r)rfrbrsr merge_result s^          rcCs|j|}|dk rt|}|jr6|j|s6tjS|jr|tj @sLtj S|tj @sZ|Sz| ||Wn$t jk r||gYdSX|SdSdS)zqLook up the given key in the given session's identity map, check the object for expired state if found. N) identity_maprQrrpinheritsmapperisaZPASSIVE_CLASS_MISMATCHZexpiredZSQL_OKZPASSIVE_NO_RESULTZRELATED_OBJECT_OKZ _load_expiredorm_excObjectDeletedErrorZ_remove_newly_deleted)rsrkeypassiver|staterrrget_from_identity[s"     rNFc Cs@|dk r|d} |d} nd} } t||| ||||| ||| d S)z.Load the given identity key from the database.Nrr )rI refresh_statewith_for_updateonly_load_propsidentity_token no_autoflushbind_argumentsrP)load_on_pk_identity) rsrtrrIrrrrrrPidentrrrr load_on_ident}s"  rc s(|} | } | j} ddlm}m}|dkr0|j}|j}|dk r| jd}|j\d|krt fddt |j |D}t |t|t|krtd| r| fdd } nt d d if| _tfd dt ||j D}nd}| rB|dk s |s |rtd d}t||||||d\}}|r|ddi7}n|dk rXd }|| _n| jdk rrd }| j| _nd}|r|jr|d|jji7}| j|j} t||||||d\| _}d| _|r|ddi7}tj| d|i} |j | || | d!"}z |#WSt$j%k r"YdSXdS)z6Load the given primary key identity from the database.r) QueryContextORMCompileStateNZplugin_subjectcs"g|]\}}|dkr|jqSr'r)rcolvalue _get_paramsrrrsz'load_on_pk_identity..zofully NULL primary key identity cannot load any object. This condition may raise an error in a future release.cs|tddiS)N _orm_adaptT)wheresql_util_deep_annotateq) _get_clauserrsz%load_on_pk_identity..rTcsg|]\}}|j|fqSrr)rZid_val primary_keyrrrrsz5refresh operation not supported with lambda statementF) version_checkrrrrjZ _current_pathZ_sa_orm_load_options)paramsrPr)&Z_cloneZ_is_lambda_elementrrrZdefault_load_optionsZdefault_compile_optionsZ_propagate_attrsrsetrMrrZadapt_criterion_to_nullrJrwarn add_criteriarZ_where_criteriarTNotImplementedError_set_get_optionsZ_for_update_argrI load_pathparentoptionsZ_compile_optionsZ _order_by EMPTY_DICTZ merge_withexecuteuniqueZscalarsZonerZ NoResultFound)rsrtZprimary_key_identityrIrrrrrrrPr~rZ is_lambdarrcompile_optionsrZnonesrr_rWr)rrrrs                 rc Cspi}i}|r||d<|r ||d<|r4||d<d|d<|rDt||d<|rP||d<|r\||7}|rh||7}||fS)NZ_version_checkZ_populate_existingZ_refresh_stateTZ_for_refresh_stateZ_only_load_propsZ_refresh_identity_token) frozenset) Z compile_optZload_optpopulate_existingrrrrrrIrrrr=s$  rc Ks|r||} n|j} i} ||jd| |oBt|dkoB|dj} | D]6} |r\| j|kr\qH| j||||f||| | d| qH|dk r||jk r|r|j |}n|}| |dS)Nmemoized_setupsr)rcolumn_collectionZmemoized_populatorscheck_for_adapt) Z_iterate_polymorphic_propertiesZ_polymorphic_propertiesrrrJis_aliased_classrsetuppolymorphic_oncolumnsrr)rHrrr=adapterrZwith_polymorphicrpolymorphic_discriminatorkwZpoly_propertiesquick_populatorsrrpdrrr_setup_entity_query]s@    rcCstdt|fdS)NamLoading context for %s has changed within a load/refresh handler, suggesting a row refresh operation took place. If this event handler is expected to be emitting row refresh operations within an existing load or refresh operation, set restore_load_context=True when establishing the listener to ensure the context remains unchanged when the event handler completes.)rrr )rrrr_warn_for_runid_changeds rc s@ jj} d f} || j| d} | dkrĈ j} dk rT|  fdd D} |jdt}g}gggggggd}dkr j}rfdd|D}||nd||d } | D]}||kr||}|t kr|d  |j |j fn|t kr|d  |j d fn|tkr8|d  |j |jfnnd}rbj|}|dk rb||d }|st||d }|r|d  |j |fn||| ||q| |q|| j| | | d}dd|D| dD]}||| |qjjjjr"jj|n|jjjp: j t jjjt jjj tjjj! rvjjj! tj"tj#jj$j%j&j'r҈ j(}|dk rΈrˆj|}||ndsp| dk rpd|jf}|jkr$j|j)dkr$ *j|j+d| }n *d| }|rp|| k rp dksNt,t-||}t./|j0|||t.1 rj dkr 2n d| d j3rtj4ntj fdd} j5r<| s<s<fdd}t6|| |||| }|S)z]Produce a mapper level row processor callable which processes rows into mapped instances.gettersNc3s|]}j|VqdSr')Z_props)rkrrr sz&_instance_processor..r)newquickdeferredexpiredelayedexistingeagercsg|]}j|qSr)r)rc)rrrrsz'_instance_processor..)cached_populatorstodoprimary_key_getterrrFrrcSsi|]\}}|t|qSr)rL)rrrrrr 5sz'_instance_processor..rloader))Zselectinload_polymorphicTentitiesrc sr,}|}|}|jk}d}d}n|f}|}|dk r|}|}|jk}| }d}rr|st |||nT|drdSd}d}d} j}|}|}||_|_|_ || }|krd}|s|r |rs|s|_ |_ t |||||| |r|j} |rrn|j j||j| krnt| rˆj||j| krt|n,r|j j| |jkrt||s|jrr r|| n ||r|dn|j} |jk}|r0| s0 drt||||| } |rr~|j} |j j|| |j| kr~t|||| rjr|d|S)NTFrr)r"rGrQ_validate_version_id class_managerZ new_instancerr session_idZ_add_unpresentrIr_populate_fullmanagerdispatchrfrrsrefreshmodifiedZ_commitZ _commit_all add_stateunloadedr6_populate_partialZinvoke_all_eagers) r0rr|dict_isnewZ currentloadloaded_instance identitykeyZeffective_populate_existingZexisting_runidrto_load)ridentity_classrrqrpis_not_primary_keyload_evtrloaded_as_persistentrrpersistent_evtr populatorsr>rpropagated_loader_options refresh_evtrefresh_identity_keyrrGrsession_identity_maprversion_id_getterrr _instances                     z&_instance_processor.._instancecs&|f}|ds|SdSdS)Nrr)r0r)rrrrrr ensure_no_pk2s z)_instance_processor..ensure_no_pk)7Z_identity_classrHrQrZ _prop_set intersectionr rZ _tuple_getterrrrrZ_deferred_column_loaderr r Z_raise_column_loaderr_getterZcreate_row_processorrr8r current_pathr=rsrrZalways_refreshboolrrrfrrrprqZhash_keyrGrrversion_id_colZstrategyZ_should_selectin_loadZ local_optsAssertionError_load_subclass_via_inPostLoadcallable_for_pathr for_context_identity_key_from_stateallow_partial_pks issupersetpolymorphic_map_decorate_polymorphic_switch)rrrrWr=rrrr_polymorphic_fromrHZ getter_keyrpropsrrrZpk_colsproprgetterZ adapted_colrrZselectin_load_viaZ callable_rrr)rrrrrqrprrrrrrrrrr>rrrrrrGrrrrr_instance_processors4                      <"  rcsP|j}t|jjdk|jr.||\n |j\fdd}|S)Nrcsb|j}jf|jf|j|d}|jr:|dd||jjfdd|DddS)N) cache_pathcSs|Sr')rrrrrr`z8_load_subclass_via_in..do_load..cs,g|]$\}}r|jddn|jdqS)rrr)rrZ load_attrs)zero_idxrrrcsz:_load_subclass_via_in..do_load..)Z primary_keys) r~Z_with_lazyload_optionsZ _with_optionsrrrrsrall)rr=states load_onlyZeffective_entityZ orig_queryZq2Z disable_optZ enable_optrr rrdo_loadVs  z&_load_subclass_via_in..do_load)rrJZ base_mapperrrZ_subclass_load_via_inZ_subclass_load_via_in_mapper)rr=entityrrrr rrLs rc Cs:|r|j|_|dD]\} } | ||| <q|r^|dD]$\} } || d| r6|j| q6n"|dD]\} } | rf|j| qf|dD]\} } | |||q|dD]\} } | |||qnx||jkr||_|dD]\} } | |kr| ||| <q|dD]\} } | |||qn |dD]\} } | |||qdS)Nrrrrr)rGpopexpired_attributesaddr) rr0rrrrrrrrr set_callable populatorrrrrls2   rc Cs|s6|j|}|dD]\} } | |kr| |||qn|}||j|<|dD]\} } | |krL| ||| <qL|dD],\} } | |krr|| d| rr|j| qr|dD]\} } | |kr| |||q|dD]\} } | |kr| |||q|dD]\} } | |kr| |||q|S)Nrrrrrr)r6rrr) rr0rrrrrrrrrrrrrrrs2   rc CsD||||j||kr@tdt|||||j||fdS)NzWInstance '%s' has version id '%s' which does not match database-loaded version id '%s'.)Z_get_state_attr_by_columnrrZStaleDataErrorr )rrrr0rrrrrs&rc sr|dk r|njdkr Sr.j fdd} t|  fdd} | S)Nc sdzj|}Wn tk r.td|Yn2X|kr.configure_subclass_mappercs|}|dk rf|}|r$||S|dkr\|}|rVtd|j|fqddSq|Sn$|}|rtd|fndSdS)NFzRow with identity key %s can't be loaded into an object; the polymorphic discriminator column '%s' refers to %s, which is not a sub-mapper of the requested %szjRow with identity key %s can't be loaded into an object; the polymorphic discriminator column '%s' is NULL)rrr)r0rrr)rr instance_fnrpolymorphic_instancesrrrpolymorphic_instance s6  z:_decorate_polymorphic_switch..polymorphic_instance)rrrZ PopulateDictr) rrrrrWr=rrrrrr) rrrrrrr=rrrrWrrs    &rc@sPeZdZdZdZddZddZddZed d Z ed d Z ed dZ dS)rz4Track loaders and states for "post load" operations.)loadersr  load_keyscCsi|_t|_d|_dSr')rr OrderedDictr r)selfrrr__init__8s zPostLoad.__init__cCs||j|<dSr')r )rr overwriterrrr=szPostLoad.add_statecsr|js dStj|}|jD]B\}}}}fdd|jD}|r |||||jf||q |jdS)Ncs&g|]\}}|jjr||fqSr)rrr)rrr limit_to_mapperrrrIsz#PostLoad.invoke..) r rZ PathRegistryZcoercervaluesr8rclear)rrr=tokenrargrr rr!rr9Ds  zPostLoad.invokecCs$|j|j}|dk r |r ||_|Sr')r7rQr=r)clsrr=rplrrrrRs zPostLoad.for_contextcCs|j|jko||j|jjkSr')r=r7r)rrr=rrrr path_existsYs zPostLoad.path_existsc OsD|j|jkr|j|j}nt}|j|j<|||||f|j|<dSr')r=r7rr) r'rr=r"r%Zloader_callabler&rr(rrrr`s zPostLoad.callable_for_pathN) __name__ __module__ __qualname____doc__ __slots__rrr9 classmethodrr)rrrrrr3s  rc st|j}|stdt|t|j}d}t|tj@p>|jj}|rT| j }j rj s||}|dk rddlm} | |td} t|| d|||d}|dkrV|r|j} n<fdd jD} |j | rtd t||} t| rjr"t| r6t d t|dSt|t!"#t$| |||d }|rp|dkrpt%|dS) z4initiate a column-based attribute refresh operation.zQInstance %s is not bound to a Session; attribute refresh operation cannot proceedFNr) FromStatement*)rrrcsg|]}j|jqSr)Z_columntopropertyr)rrrrrrsz*load_scalar_attributes..z_Instance %s cannot be refreshed - it's not persistent and does not contain a full primary key.zwInstance %s to be refreshed doesn't contain a full primary key - can't be refreshed (and shouldn't be expired, either).)rrr)&rsrZDetachedInstanceErrorr rrrZ NO_AUTOFLUSHZ autocommitrattrsrxrZconcreteZ_optimized_get_statementr~r0rrLoadZundeferrrrrrrr issubsetrrrZ warn_limitedrselectZset_label_stylerr) rrZattribute_namesrrsZhas_keyrWrrtr0ZstmtZ identity_keyZpk_attrsrrrload_scalar_attributesks            r6)T)T)NNNNN)NNN)NNNN)3r- __future__rrrrrrbaserr r rr r rrZenginerZ engine.resultrrrZsqlrZsql.selectablercounterrFrXZpreload_moduler{ deprecatedrrrrrrrrrrrrrrobjectrr6rrrrs                   ( ;K& & " ' : , :"Y8