U kf @sdZddlmZddlZddlmZddlZddlZddlZddl Z ddl Z ddl m Z ddl m Z ddl m Z ddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddlZddlm Z ddlm!Z!ddl"m#Z#ddl"m$Z$ddl%m&Z&ddl%m'Z'ddl%m(Z(dd l%m)Z)dd!l%m*Z*dd"l%m+Z+dd#l%m,Z,dd$l%m-Z-dd%l.m/Z/dd&l.m0Z0dd'l.m1Z1dd(l.m2Z2dd)l.m3Z3dd*l.m4Z4dd+l.m5Z5dd,l.m6Z6dd-l7m8Z8dd.l7m9Z9dd/l7m:Z:d0d1lm;Z<d0d2lm=Z=d0d3lm>Z>d0d4lm?Z?d0d5lm@Z@d0d6lm7Z7d0d7lAmZd0d8l@mBZBd0d9l@mCZCd0d:l@mDZDd0d;l@mEZEd0dlGmIZId0d?lJmKZKd0d@lLmMZMd0dAlLmNZNd0dBlOmPZPd0dClOmQZQd0dDlOmRZRd0dElOmSZSd0dFlOmTZTd0dGlOmUZUd0dHlOmVZVd0dIlOmWZWd0dJlXmYZYd0dKlXmZZZd0dLlXm[Z[e j\rddMl"m]Z]ddNl"m^Z^ddOl"m_Z_ddPl"m`Z`ddQl"maZaddRl"mbZbddSl"mcZcddTl%mdZdddUlemfZfddVlemgZgddWlhmiZiddXljmkZkddYllmmZmddZlnmoZodd[lpmqZqdd\lrmsZsdd]ltmuZudd^l7mvZvdd_l7mwZwd0d`lGmxZxd0dalGmyZyd0dblGmzZzd0dclJm{Z{d0ddlJm|Z|d0delLm}Z}d0dflLm~Z~d0dglLmZd0dhlmZd0dilmZd0djlXmZd0dklXmZedle dmZedne dmZedoe dmZedpe dmZedqe dmZeeeee geefdrdse gdrfe gdsffZeZdtZeeeHefZeduee gduffZeeZdveeHe e geHe fe geeHe feeeeHe ffZeeeeeee fffZeeMe eIe eEjdwfZeeeee geefe gefefZedxeHe dmZedydzdmZeeeNe eNe fZeeeNe eNe fZeeeNe eNe fZdxdxd{d|d}Zdxdxd{d~dZejGdddeeefZeeZdveeNe dffZGdddeZe>jGddde0e6ee>jZdyddydddZGdddZGdddZeddZed}dZGdddeee&eZGdddeee-ee)eZdS)a Heuristics related to join conditions as used in :func:`_orm.relationship`. Provides the :class:`.JoinCondition` object, which encapsulates SQL annotation and aliasing behavior focused on the `primaryjoin` and `secondaryjoin` aspects of :func:`_orm.relationship`. ) annotationsN)abc)Any)Callable)cast) Collection)Dict) FrozenSet)Generic)Iterable)Iterator)List) NamedTuple)NoReturn)Optional)Sequence)Set)Tuple)Type)TypeVar)Union) attributes)strategy_options)insp_is_aliased_class)is_has_collection_adapter)_DeclarativeMapped)_is_mapped_class) class_mapper) DynamicMapped)LoaderCallableStatus) PassiveFlag) state_str)WriteOnlyMapped)_AttributeOptions)_IntrospectsAnnotations) MANYTOMANY) MANYTOONE) ONETOMANY)PropComparator)RelationshipDirection)StrategizedProperty) _orm_annotate)_orm_deannotate)CascadeOptions)exc)Exists)log)schema)sql)util)inspect) coercions) expression) operators)roles)visitors)_ColumnExpressionArgument)_HasClauseElement)_safe_annotate) ColumnClause) ColumnElement_deep_annotate)_deep_deannotate)_shallow_annotate)adapt_criterion_to_null) ClauseAdapter)join_condition)selectables_overlapvisit_binary_product)de_optionalize_union_types)Literal)resolve_name_to_real_class_name) _EntityType)_ExternalEntityType)_IdentityKeyType) _InstanceDict)_InternalEntityType)_O) _RegistryType)Mapped)_class_resolver)_ModNS)_ClassScanMapperConfig)DependencyProcessor)Mapper)Query)Session) InstanceState) LazyLoader) AliasedClass) AliasedInsp)_CoreAdapterProto)_EquivalentColumnMap) _InfoType)_AnnotationDict)SupportsAnnotations)BinaryExpression) BindParameter) ClauseElement)Table) FromClause)_AnnotationScanType)RODescriptorReference_T)bound_T1_T2_PT_PT2 Mapper[_T]zAliasedClass[_T]) selectZjoinedZselectinZsubqueryraiseZ raise_on_sqlZnoloadZ immediate write_onlydynamicTFNrjFz Mapped[Any]_CEA_CEColumnElement[Any])exprreturncCstttj|ddiS)aAnnotate a portion of a primaryjoin expression with a 'remote' annotation. See the section :ref:`relationship_custom_foreign` for a description of use. .. seealso:: :ref:`relationship_custom_foreign` :func:`.foreign` remoteT_annotate_columnsr7expectr:ColumnArgumentRoler{rL/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/orm/relationships.pyr}s r}cCstttj|ddiS)aAnnotate a portion of a primaryjoin expression with a 'foreign' annotation. See the section :ref:`relationship_custom_foreign` for a description of use. .. seealso:: :ref:`relationship_custom_foreign` :func:`.remote` foreignTr~rrrrrs rc@sLeZdZUdZdZded<ded<ded<d d d d Zd ddddZdS)_RelationshipArgztstores a user-defined parameter value that must be resolved and parsed later at mapper configuration time. )nameargumentresolvedstrrrorz Optional[_T2]rboolr|cCs |jdk SN)rselfrrr _is_populatedsz_RelationshipArg._is_populated&Callable[[str, bool], _class_resolver]None)clsregistry_resolverr|cCsJ|j}t|tr&|||jdk|_n t|r@t|s@||_n||_dS)N secondary)r isinstancerrrcallabler)rrZ attr_valuerrr_resolve_against_registrys   z*_RelationshipArg._resolve_against_registryN)__name__ __module__ __qualname____doc__ __slots____annotations__rrrrrrrs r.c@sBeZdZUdZded<ded<ded<ded<d ed <d ed <d S) _RelationshipArgszWstores user-passed parameters that are resolved at mapper configuration time. zP_RelationshipArg[Optional[_RelationshipSecondaryArgument], Optional[FromClause]]rz\_RelationshipArg[Optional[_RelationshipJoinConditionArgument], Optional[ColumnElement[Any]]] primaryjoin secondaryjoinz>_RelationshipArg[_ORMOrderByArgument, _RelationshipOrderByArg]order_byzN_RelationshipArg[Optional[_ORMColCollectionArgument], Set[ColumnElement[Any]]] foreign_keys remote_sideN)rrrrrrrrrrs rc'sTeZdZUdZejZdZdZdZ de d<de d<e ddddddZ d Z d e d <d e d <de d<de d<de d<de d<de d<de d<de d<de d<de d<de d<de d<d e d!<d"e d#<dd d d d d dd d dd$dd d%ddddd d d d ddd dd d d d d ddd dd&"d'd(d)d*d+d+d,d-d.d,d/d0d/d1d2d3d/d/d/d4d4d5d6d/d/d)d/d7d8d9d)d,d:d;dd/d<$fd=d>Zd?d@dAdBdCZdDd@dEdFdGZGdHdIdIejeeZddJd/dKd dLdMdNZdd?d/dOd/d dPdQdRZdDdSdTdUdVdWdXdYZdd/dOd dZd[d\Zd0d]d^d_Zd`dSdTdSdTd/dadbd@dc dddeZejfdfdTd0dgdhdidjdkZdd0dSdTdldmdndodpdqZe d/d]drdsZ!e"dtdtd@dudvdwZ#d0d@dxdydzZ$ej%d{d]d|d}Z&ej%d~d]ddZ'd@d]fdd Z(d@d]ddZ)d@d]ddZ*dddd,d0dddd/d@d ddZ+e,ddd?d@dddZ-d@d]ddZ.e dd]ddZ/e dd]ddZ0ej%e,ddd]ddZ1d@d]ddZ2e dd]ddZ3e3j4dd@dddZ3dd@dddZ5dd@dddZ6dDd/dEddZ7dUd/dddZ8d@d]ddZ9e,dd@d]ddZ:ej%d/d]ddZ;ej%d/d]ddZ
S)RelationshipPropertyzDescribes an object property that holds a single item or list of items that correspond to a related database table. Public constructor is the :func:`_orm.relationship` function. .. seealso:: :ref:`relationship_config_toplevel` Tz Sequence[str] _overlapsr^_lazy_strategyFpassive_deletespassive_updatesenable_typechecksactive_historycascade_backrefsNzOptional[DependencyProcessor]_dependency_processorColumnElement[bool]rOptional[ColumnElement[bool]]rOptional[FromClause]r JoinCondition_join_condition_RelationshipOrderByArgrSet[ColumnElement[Any]]_user_defined_foreign_keys_calculated_foreign_keysr local_columns _ColumnPairssynchronize_pairsOptional[_ColumnPairs]secondary_synchronize_pairslocal_remote_pairsr* directionr _init_argszsave-update, mergert)"uselistcollection_classrrback_populatesrbackrefoverlaps post_updatecascadeviewonlyattribute_optionslazyrrrrrr join_depthcomparator_factory single_parent innerjoindistinct_target_keyload_on_pending query_classinfo omit_join sync_backrefdoc bake_queriesr_local_remote_pairs_legacy_inactive_history_stylez'Optional[_RelationshipArgumentType[_T]]z(Optional[_RelationshipSecondaryArgument]zOptional[bool]zEOptional[Union[Type[Collection[Any]], Callable[[], Collection[Any]]]]z,Optional[_RelationshipJoinConditionArgument]z Optional[str]_ORMOrderByArgumentzOptional[ORMBackrefArgument]rrzOptional[_AttributeOptions]_LazyLoadArgumentTypezUnion[Literal['all'], bool]z#Optional[_ORMColCollectionArgument]z Optional[int]z4Optional[Type[RelationshipProperty.Comparator[Any]]]zOptional[Type[Query[Any]]]zOptional[_InfoType]zLiteral[(None, False)]z Literal[True]zLiteral[False])$rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrc"% stj|d||_||_ttd|dtd|dtd|dtd|dtd|dtd|d|_| |_| |_| r|j |||||"d| r|rt d ||_ ||_ ||_||_||_|"rt d ||_||_||_||_||_| |_||_|$|_||_|rtd ||_|#|_||_|p"tj |_!t"||dk rF|j#$|d |j ff|_%t&|_'| rvt&t()d | |_*nd|_*| |_+||_,|j,r| rt dd|_-n| |_-dS)N)rrrrrrrrz-sync_backref and viewonly cannot both be TruezSThe 'cascade_backrefs' parameter passed to relationship() may only be set to False.zsetting omit_join to True is not supported; selectin loading of this relationship may not work correctly if this flag is set explicitly. omit_join optimization is automatically detected for conditions under which it is supported.rz\s*,\s*rzCbackref and back_populates keyword arguments are mutually exclusive).super__init__rrrrrrr _warn_for_persistence_only_flagssa_exc ArgumentErrorrrrrrrrrrrrrrrr5warnrrrr ComparatorrZset_creation_orderrupdate strategy_keyset_reverse_propertyresplitrrrr)%rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr __class__rrrns,           zRelationshipProperty.__init__rr)kwr|cKs4|D]&\}}||j|krtd|fqdS)NzSetting %s on relationship() while also setting viewonly=True does not make sense, as a viewonly=True relationship does not perform persistence operations. This configuration may raise an error in a future release.)items_persistence_onlyr5r)rrkvrrrrsz5RelationshipProperty._warn_for_persistence_only_flagsz Mapper[Any])mapperr|cCs&tj|j|j|||||jddS)N)Z comparator parententityr)rZregister_descriptorclass_keyrrrrrrrinstrument_class s z%RelationshipProperty.instrument_classc@sVeZdZUdZdZded<ded<dHd d d dd d ddZdddddZded<ded<ddddZddddZ dddd Z d!dd"d#Z d$d%d&d'd(Z d)d*d+d,d-Z d.d/d0d1d2ZdZd.d!d0d3d4ZdId5d.d6d7d8d9ZdJd5d.d!d7d:d;ZdKd5d.d!d7dd.d!d?d@dAZd.d!d0dBdCZd.d!d0dDdEZd ddFdGZdS)LzRelationshipProperty.ComparatoraProduce boolean, comparison, and other operators for :class:`.RelationshipProperty` attributes. See the documentation for :class:`.PropComparator` for a brief overview of ORM level operator definition. .. seealso:: :class:`.PropComparator` :class:`.ColumnProperty.Comparator` :class:`.ColumnOperators` :ref:`types_operators` :attr:`.TypeEngine.comparator_factory` )entityrproperty_of_type_extra_criteriaz0RODescriptorReference[RelationshipProperty[_PT]]propzOptional[_EntityType[_PT]]rNrzRelationshipProperty[_PT]z_InternalEntityType[Any]zOptional[AliasedInsp[Any]]Tuple[ColumnElement[bool], ...])r parentmapperadapt_to_entityof_typeextra_criteriacCs.||_||_||_|r||_nd|_||_dS)zConstruction of :class:`.RelationshipProperty.Comparator` is internal to the ORM's attribute mechanics. N)r _parententity_adapt_to_entityrr)rrrrrrrrrr3s z(RelationshipProperty.Comparator.__init__zAliasedInsp[Any]z$RelationshipProperty.Comparator[Any])rr|cCs|j|j|j||jdS)N)rr)rrrr)rrrrrrHs z/RelationshipProperty.Comparator.adapt_to_entityz_InternalEntityType[_PT]rz Mapper[_PT]rrcCs|jrt|jS|jjSdSr)rr6rrrrrr_memoized_attr_entitygs z5RelationshipProperty.Comparator._memoized_attr_entitycCs|jjSrrrrrrr_memoized_attr_mappermsz5RelationshipProperty.Comparator._memoized_attr_mapperrjcCs|jr|jjS|jjjSdSr)r selectablerparent_with_polymorphic_selectablerrrr_source_selectablepsz2RelationshipProperty.Comparator._source_selectablerc CsZ|}|jrt|j}nd}|jj|d|d|jd\}}}}}}|dk rR||@S|SdS)NT)source_selectablesource_polymorphicof_type_entityalias_secondaryr)rrr6r _create_joinsr) rZ adapt_fromrpjsjsourcedestrtarget_adapterrrr__clause_element__vs*  z2RelationshipProperty.Comparator.__clause_element__z_EntityType[Any]zPropComparator[_PT])rr|cCstj|j|j|j||jdS)zRedefine this object in terms of a polymorphic subclass. See :meth:`.PropComparator.of_type` for an example. rrr)rrrrrr)rrrrrrsz'RelationshipProperty.Comparator.of_typez_ColumnExpressionArgument[bool]zPropComparator[Any])criteriar|cGs:tddt|D}tj|j|j|j|j|j |dS)zAdd AND criteria. See :meth:`.PropComparator.and_` for an example. .. versionadded:: 1.4 css|]}ttj|VqdSr)r7rr:WhereHavingRole).0clauserrr sz7RelationshipProperty.Comparator.and_..r) tupler5Zcoerce_generator_argrrrrrrr)rrZexprsrrrand_s z$RelationshipProperty.Comparator.and_rr)otherr|cCs tddS)zProduce an IN clause - this is not implemented for :func:`_orm.relationship`-based attributes at this time. zvin_() not yet supported for relationships. For a simple many-to-one, use in_() against the set of foreign key values.N)NotImplementedErrorrrrrrin_sz#RelationshipProperty.Comparator.in_cCst|dkst|tjrF|jjttfkr.|St|jj d|j dSn*|jj rZt dnt|jj ||j dSdS)aImplement the ``==`` operator. In a many-to-one context, such as:: MyClass.some_prop == this will typically produce a clause such as:: mytable.related_id == Where ```` is the primary key of the given object. The ``==`` operator provides partial functionality for non- many-to-one comparisons: * Comparisons against collections are not supported. Use :meth:`~.Relationship.Comparator.contains`. * Compared to a scalar one-to-many, will produce a clause that compares the target columns in the parent to the given target. * Compared to a scalar many-to-many, an alias of the association table will be rendered as well, forming a natural join that is part of the main body of the query. This will not work for queries that go beyond simple AND conjunctions of comparisons, such as those which use OR. Use explicit joins, outerjoins, or :meth:`~.Relationship.Comparator.has` for more comprehensive non-many-to-one scalar membership tests. * Comparisons against ``None`` given in a one-to-many or many-to-many context produce a NOT EXISTS clause. N adapt_source]Can't compare a collection to an object or collection; use contains() to test for membership.)rr8Nullrrr(r&_criterion_existsr,_optimized_compareadapterrrInvalidRequestErrorrrrr__eq__s&% z&RelationshipProperty.Comparator.__eq__z)Optional[_ColumnExpressionArgument[bool]]r1) criterionkwargsr|cKs|dk rttj|nd}t|ddrt|j}|dk s Where ```` is the value of the foreign key attribute on ``other`` which refers to the primary key of its parent object. From this it follows that :meth:`~.Relationship.Comparator.contains` is very useful when used with simple one-to-many operations. For many-to-many operations, the behavior of :meth:`~.Relationship.Comparator.contains` has more caveats. The association table will be rendered in the statement, producing an "implicit" join, that is, includes multiple tables in the FROM clause which are equated in the WHERE clause:: query(MyClass).filter(MyClass.contains(other)) Produces a query like:: SELECT * FROM my_table, my_association_table AS my_association_table_1 WHERE my_table.id = my_association_table_1.parent_id AND my_association_table_1.child_id = Where ```` would be the primary key of ``other``. From the above, it is clear that :meth:`~.Relationship.Comparator.contains` will **not** work with many-to-many collections when used in queries that move beyond simple AND conjunctions, such as multiple :meth:`~.Relationship.Comparator.contains` expressions joined by OR. In such cases subqueries or explicit "outer joins" will need to be used instead. See :meth:`~.Relationship.Comparator.any` for a less-performant alternative using EXISTS, or refer to :meth:`_query.Query.outerjoin` as well as :ref:`orm_queryguide_joins` for more details on constructing outer joins. kwargs may be ignored by this operator but are required for API conformance. z9'contains' not implemented for scalar attributes. Use ==rN) rrrr$r"r#r'_Comparator__negated_contains_or_equalsZnegation_clause)rrr'rrrrcontainss= z(RelationshipProperty.Comparator.containscsjjtkrjt|dddddfdd dddfd d jjrjtjfd d jj DStjd d t jj j jj |D}|S)NrzInstanceState[Any]BindParameter[Any]) local_colstate remote_colr|c s.|j}tj|j|jdjjj|||dS)NT)type_uniqueZ callable_)dictr4 bindparamrtyper_get_attr_w_warn_on_noner)rBrCrDdict_rrrstate_bindparamszURelationshipProperty.Comparator.__negated_contains_or_equals..state_bindparamry)colr|csjr|S|SdSr)r#rMrrradapt#s zKRelationshipProperty.Comparator.__negated_contains_or_equals..adaptc s8g|]0\}}t|||k|dkqSr)r4or_rxy)rOrCrLrr +s zPRelationshipProperty.Comparator.__negated_contains_or_equals..cSsg|]\}}||kqSrrrQrrrrT6s)rrr'rinstance_stater_use_getr4rrziprZ primary_keyZprimary_key_from_instancer!)rrr&r)rOrrCrLrZ__negated_contains_or_equalss&     z This will typically produce a clause such as:: mytable.related_id != Where ```` is the primary key of the given object. The ``!=`` operator provides partial functionality for non- many-to-one comparisons: * Comparisons against collections are not supported. Use :meth:`~.Relationship.Comparator.contains` in conjunction with :func:`_expression.not_`. * Compared to a scalar one-to-many, will produce a clause that compares the target columns in the parent to the given target. * Compared to a scalar many-to-many, an alias of the association table will be rendered as well, forming a natural join that is part of the main body of the query. This will not work for queries that go beyond simple AND conjunctions of comparisons, such as those which use OR. Use explicit joins, outerjoins, or :meth:`~.Relationship.Comparator.has` in conjunction with :func:`_expression.not_` for more comprehensive non-many-to-one scalar membership tests. * Comparisons against ``None`` given in a one-to-many or many-to-many context produce an EXISTS clause. Nrr)rr8r rrr'r,r"r#r!rrr$r>rrrr__ne__As'  z&RelationshipProperty.Comparator.__ne__cCs|jj|jSr)rr_check_configurerrrr_memoized_attr_property{s z7RelationshipProperty.Comparator._memoized_attr_property)NNr)N)N)N)rrrrrrrrrrrrrrr__hash__r%r!r<r=r?r>rXrZrrrrrs<     <h7&N3:robjectzOptional[_EntityType[Any]])instancer  from_entityr|cCsN|dk s td}|dk r.visit_bindparamrH)r6rNoInspectionAvailabler+r_lazy_none_clauser _lazywhere _bind_to_col_rev_lazywhere_rev_bind_to_colrrr instance_dictobjrrFr/r1r;cloned_traverse)rrCr_rr reverse_directionr&rcrrarr"sV   z'RelationshipProperty._optimized_comparer@rQrzzCallable[[], Any])rrCrKcolumnr|cs<jjddfdd }|S)aKCreate the callable that is used in a many-to-one expression. E.g.:: u1 = s.query(User).get(5) expr = Address.user == u1 Above, the SQL should be "address.user_id = 5". The callable returned by this method produces the value "5" based on the identity of ``u1``. rrcsdk s tj}}|tjk }jjr:tjn tjtj Ad}|tj krp|st dt fn*|tjkr|st dt fn|}|dkrtd|S)NpassivezUCan't resolve value for column %s on object %s; no value has been set for this columnz`Can't resolve value for column %s on object %s; the object is detached and the value was expiredzGot None for value of column %s; this is unsupported for a relationship comparison and will not currently produce an IS comparison (but may in a future release))r,rr ZNO_VALUEZ_get_state_attr_by_column persistentr! PASSIVE_OFFZPASSIVE_NO_FETCHZINIT_OKZ NEVER_SETrr$r"PASSIVE_NO_RESULTr5r)Z last_knownZ to_returnZexisting_is_available current_valuernrKZ lkv_fixedrrrCrr_gosD      z:RelationshipProperty._get_attr_w_warn_on_none.._go)Zget_property_by_columnZ_track_last_known_valuerZ_last_known_values)rrrCrKrnrvrrurrJs 1  /z-RelationshipProperty._get_attr_w_warn_on_none)rmrr|cCsD|s|jj|jj}}n|jj|jj}}t||}|r@||}|Sr)rrfrgrhrirE)rrmrr&rbrrrreBs z&RelationshipProperty._lazy_none_clausercCst|jjjd|jS)N.)rrrrrrrrr__str__XszRelationshipProperty.__str__r\zDict[Any, object]z#Dict[_IdentityKeyType[Any], object]) session source_state source_dict dest_state dest_dictload _recursive_resolve_conflict_mapr|c Cs|r"|jD]} || f|kr dSq d|jkr0dS|j|kr>dS|jrR||j} t| s^t| ||} | jrx| j rndst|r||jj ||t j dg} | D]J} t | }t | }d|||f<|j|||||d}|dk r| |q|s t |||j}| D]}||q n0||j}t|s:t|j||| dt j dnx||j} | dk rt | }t | }d|||f<|j|||||d}nd}|s|||j<n||j|||ddS)NmergeTro)r~rrF)Z_adaptrp)r_cascaderrZget_implrr,get_collection collectionemptygetr!Z PASSIVE_MERGErrUrj_mergeappendZinit_state_collectionZappend_without_eventr)rryrzr{r|r}r~rrrimplZinstances_iterableZ dest_listcurrentZ current_stateZ current_dictrkZcollcZ dest_implrrrr[s                     zRelationshipProperty.mergezInstanceState[_O]r!z&Sequence[Tuple[InstanceState[_O], _O]])rCrKrrpr|cCsj|j|j}|j|||d}|tjks.|dkr2gSt|rVdd|j||||dDSt||fgSdS)zReturn a list of tuples (state, obj) for the given key. returns an empty list if the value is None/empty/PASSIVE_NO_RESULT roNcSsg|]}t||fqSr)rrU)rorrrrTsz;RelationshipProperty._value_as_iterable..) managerrrr rsrrrrU)rrCrKrrprrRrrr_value_as_iterables z'RelationshipProperty._value_as_iterablezSet[InstanceState[Any]]z.Optional[Callable[[InstanceState[Any]], bool]]zDIterator[Tuple[Any, Mapper[Any], InstanceState[Any], _InstanceDict]])rErCrKvisited_stateshalt_onr|c cs|dks|jrtj}n tjtjB}|dkrB|j|jj||}n|j |||j|d}|dkofd|j k}|D]\} } | |kr~ql| dkrql| dk st t | } |r|| rql|r| jsql| jj} | |jjjst d|j|jj| jf|| | | | | fVqldS)Ndeletez save-updaterozrefresh-expire delete-orphanz@Attribute '%s' on class '%s' doesn't handle objects of type '%s')rr!ZPASSIVE_NO_INITIALIZErrZNO_RAISErrrZget_all_pendingrrr,rrjrZisaZ class_managerrrradd) rrErCrKrrrpZtuplesZ skip_pendingrUrrjZinstance_mapperrrrcascade_iteratorsB        z%RelationshipProperty.cascade_iteratorcCs|jr dS|jdk SdS)NF)rrrrrr_effective_sync_backrefsz,RelationshipProperty._effective_sync_backrefRelationshipProperty[Any])rel_arel_br|cCs>|jr|jrtd||f|jr:|js:|jdk r:d|_dS)NzQRelationship %s cannot specify sync_backref=True since %s includes viewonly=True.F)rrrr$)rrrrr_check_sync_backrefs z(RelationshipProperty._check_sync_backref)rr|cCs|jj|dd}t|ts,td||f|||||||j||j|| |j |j st d||||j f|j r|jttfkr|j|jkrt d|||jfdS)NF)Z_configure_mapperszback_populates on relationship '%s' refers to attribute '%s' that is not a relationship. The back_populates parameter should refer to the name of a relationship on the target class.zereverse_property %r on relationship %s references relationship %s, which does not reference mapper %szv%s and back-reference %s are both of the same direction %r. Did you mean to set remote_side on the many-to-one side ?)rZ get_propertyrrrr$rrr _setup_entity common_parentrrZ_configure_startedrr(r')rrrrrr_add_reverse_property)s:         z*RelationshipProperty._add_reverse_propertyz_InternalEntityType[_T]cCs|j|jS)zReturn the target mapped entity, which is an inspect() of the class or aliased class that is referenced by this :class:`.RelationshipProperty`. )rrYrrrrrrUs zRelationshipProperty.entityrscCs|jjS)zcReturn the targeted :class:`_orm.Mapper` for this :class:`.RelationshipProperty`. rrrrrr_szRelationshipProperty.mappercsn|||||||j|||j t t d|d|_dS)Nr^))rrt)_check_conflicts_process_dependent_argumentsr_setup_registry_dependencies_setup_join_conditions_check_cascade_settingsr _post_init_generate_backrefr"_warn_for_conflicting_sync_targetsrdo_initrZ _get_strategyrrrrrrgs   zRelationshipProperty.do_initcCs|jjj|jjjdSr)rrregistryZ_set_depends_onrrrrrrvs z1RelationshipProperty._setup_registry_dependenciescCs|j}dD]}t||}||jdq dD]4}t||}|j}|dk r.ttjtj ||d|_q.|j j}|dk rt |rt d||f|jjdk r|jjdk rtdd t|jjD|_nd|_td d t|jjD|_td d t|jjD|_dS) zConvert incoming configuration arguments to their proper form. Callables are resolved, ORM annotations removed. )rrrrrrr)rrNargnamezsecondary argument %s passed to to relationship() %s must be a Table object or other FROM clause; can't send a mapped class directly as rows in 'secondary' are persisted independently of a class that is mapped to that same table.Fcss |]}tjtj|ddVqdS)rrNr7rr:rrrRrrrrs zDRelationshipProperty._process_dependent_arguments..css |]}tjtj|ddVqdS)rrNrrrrrrs css |]}tjtj|ddVqdS)rrNrrrrrrs )rr+r_clsregistry_resolversrr-r7rr:rrrrrrrr5Zto_list column_setZ to_column_setrrr)rZ init_argsattrZrel_argvalrrrrr{sH          z1RelationshipProperty._process_dependent_argumentsrXrTz Type[Any]zOptional[Type[Mapped[Any]]]zOptional[_AnnotationScanType]) decl_scanrclsoriginating_modulermapped_container annotationextracted_mapped_annotationis_dataclass_fieldr|c Cs|} |dkr(|jdkr$|||ndS|} |dk s8t|dk rt|t} t|t} | rnd|_d|jff|_q| rd|_d|jff|_nd} } t| } t | drl| j } t | t rt| t jr|jdkrt| rtd| d| |_n| s| sd|_| jrXt | t r*t| tjr*| jd}n | jd }t |d rR|j}t||} n|} ntd | d nt | d r| j} t| |} |jdkr| s| sd|_|jdkrtd | |_dS)NrvrrwF __origin__zCollection annotation type z cannot be instantiated; please provide an explicit 'collection_class' parameter (e.g. list, set, etc.) to the relationship() function to accompany this annotationr__forward_arg__zGeneric alias z requires an argumentz_RelationshipArgumentType[_T])rZ_raise_for_requiredr, issubclassr#rrrrKhasattrrrrIrrr _py_inspect isabstractrrr__args__typingMappingrrMr)rrrrrrrrrrrZ is_write_onlyZ is_dynamicZ arg_originZtype_argZ str_argumentrrrdeclarative_scans                 z%RelationshipProperty.declarative_scanzsqlalchemy.orm.mapper)_RelationshipProperty__argumentr|cCsd|jkrdStjj}|r |}n|j}t|trDtd||}n$t |rdt|t |j fsd|}n|}t|t rt |dd}nJz t |}Wntjk rd}YnXt|dstd|jt |f||_|jj|_dS)Nrz_ExternalEntityType[Any]F configurerzErelationship '%s' expects a class or a mapper argument (received: %s))__dict__r5 preloadedZ orm_mapperrrrr_clsregistry_resolve_namerrIrZrr6rrdrrrrpersist_selectabletarget)rrZ mapperlibrZresolved_argumentrrrrr+s>         z"RelationshipProperty._setup_entitycCst|jj|jj|jj|jj|jjj|jjj|jj j|jj |j j |j |j |j|j||j |jd|_}|j|_|j |_ |j|_|j|_|j |_ |j|_|j|_|j|_|j|_|j|_dS)Nparent_persist_selectablechild_persist_selectableparent_local_selectablechild_local_selectablerrrparent_equivalentschild_equivalentsconsider_as_foreign_keysrrself_referentialr support_synccan_be_synced_fn)rrrr local_tablerrrrrZ_equivalent_columnsrrrrr.r_columns_are_mappedrrremote_columnsrrforeign_key_columnsrr)rZjcrrrr[s8 z+RelationshipProperty._setup_join_conditionsrcCs |jdS)Nrrrrrr_clsregistry_resolve_argysz-RelationshipProperty._clsregistry_resolve_argz>Callable[[str], Callable[[], Union[Type[Any], Table, _ModNS]]]cCs |jdS)Nrrrrrrrsz.RelationshipProperty._clsregistry_resolve_namezsqlalchemy.orm.clsregistryzmTuple[Callable[[str], Callable[[], Union[Type[Any], Table, _ModNS]]], Callable[[str, bool], _class_resolver]]cCstjjj}||jj|Sr)r5rZorm_clsregistry _resolverrr)rrrrrrs z+RelationshipProperty._clsregistry_resolverscCsF|jjrBt|jjdd|jsBtd|j|jjj|jjjfdS)zOTest that this relationship is legal, warn about inheritance conflicts.FrzAttempting to assign a new relationship '%s' to a non-primary mapper on class '%s'. New relationships can only be added to the primary mapper, i.e. the very first mapper created for class '%s' N) r non_primaryrr has_propertyrrrrrrrrrs z%RelationshipProperty._check_conflictsr.cCs|jS)z\Return the current cascade setting for this :class:`.RelationshipProperty`. )rrrrrrszRelationshipProperty.cascadezUnion[str, CascadeOptions])rr|cCs||dSr) _set_cascaderrrrrrs) cascade_argr|cCsJt|}|jrt|tj}d|jkr2||||_|jrF||j_dS)Nr) r.r intersectionZ_viewonly_cascadesrrrrr)rrrrrrrs   z!RelationshipProperty._set_cascadecCs|jrV|jsV|jtks |jtkrVtjd||jtkr6dnd|jjj |j jj ddd|j dkr~d|kspd |kr~td ||jr|j j |j|jjfdS) NaFor %(direction)s relationship %(rel)s, delete-orphan cascade is normally configured only on the "one" side of a one-to-many relationship, and not on the "many" side of a many-to-one or many-to-many relationship. To force this relationship to allow a particular "%(relatedcls)s" object to be referenced by only a single "%(clsname)s" object at a time via the %(rel)s relationship, which would allow delete-orphan cascade to take place in this direction, set the single_parent=True flag.z many-to-onez many-to-many)relrZclsnameZ relatedclsZbbf0codeallrrz^On %s, can't set passive_deletes='all' in conjunction with 'delete' or 'delete-orphan' cascade)Z delete_orphanrrr&r'rrrrrrrprimary_mapperZ_delete_orphansrrrrrrrsD   z,RelationshipProperty._check_cascade_settingscCs|j|jko|j|j|kS)zaReturn True if this property will persist values on behalf of the given mapper. )rZ relationshipsrrrr _persists_fors z"RelationshipProperty._persists_for)colsr|cGsR|jjj}|D]>}|dk r(|j|r(q|jjj|s|jj|sdSqdS)zReturn True if all columns in the given collection are mapped by the tables referenced by this :class:`.RelationshipProperty`. NFT)rrrrcontains_columnrrr)rrrrrrrrs   z(RelationshipProperty._columns_are_mappedc Cs|jjr dS|jdk rr|jsrt|jtr:|ji}}n |j\}}|j}|jst |  |j }|D](}| |rl|jsltd|||fql|jdk r|d|jj}|d|jj}n*|d|jj}|dd}|rtd|d|j}|j} |d|j|d|j|d |j|d |j||_t| |jf||||jd |} |j|| d d |jr| |jdS)zlInterpret the 'backref' instruction to create a :func:`_orm.relationship` complementary to this one.Nz]Error creating backref '%s' on relationship '%s': property of that name exists on mapper '%s'rrzOCan't assign 'secondaryjoin' on a backref against a non-secondary relationship.rrrrr)rrrrT)Zwarn_for_existing)!rrrrrrrrZconcreterZiterate_to_rootunionZself_and_descendantsrrrrpoprsecondaryjoin_minus_localprimaryjoin_minus_localprimaryjoin_reverse_remoter$r setdefaultrrrrrrZ_configure_propertyr) rZ backref_keyr'rcheckmr r rrZ relationshiprrrrs        z&RelationshipProperty._generate_backrefzsqlalchemy.orm.dependencycCs6tjj}|jdkr|jtk |_|js2|j||_ dSr) r5rZorm_dependencyrrr'rrYZfrom_relationshipr)r dependencyrrrrWs  zRelationshipProperty._post_initcCs |j}|jS)zPmemoize the 'use_get' attribute of this RelationshipLoader's lazyloader.)rZuse_get)rZstrategyrrrrVbszRelationshipProperty._use_getcCs|j|jSr)rrrrrrrr.jsz)RelationshipProperty._is_self_referentialrz"Optional[_InternalEntityType[Any]]rzTuple[ColumnElement[bool], Optional[ColumnElement[bool]], FromClause, FromClause, Optional[FromClause], Optional[ClauseAdapter]])rrr(rr rr|cCsd}|r|jdk rd}|dkr2|r2|jjr2|jj}|rP|j}|dkrV|j}d}n|j}|dkr|jj}|jjrrd}|jr|dkr|}d}n||jjk s|jjrd}|j } |p|dk o||jjk p|j }|j |||| |\} } } } }|dkr|jj }|dkr |jj }| | ||| | fS)NFT)rrZwith_polymorphicrrrrr.r/r0Z _is_subqueryr join_targetsr)rrrr(rr raliasedZ dest_mapperr6rrrrrrrr nsp   z"RelationshipProperty._create_joins)NN)TN)FNT)FN)N)N)FNNNFr)?rrrrrZ_RELATIONSHIP_TOKENZstrategy_wildcard_key inherit_cacheZ_links_to_entityZ_is_relationshiprrGrrrrrr5Z MemoizedSlotsr)rqrr`r"rJrerxrr!rrrrrr staticmethodrrmemoized_propertyrrrrrrZpreload_modulerrrrrrrsetterrrrrrrrVr.r  __classcell__rrrrr5s   \  sDmf=, L d/ . P rrd)elementrr|cs.dddfdd |dk r&|}d|S)Nry)elemr|cs*t|tjr|}|jd|S)N)clone)rr8r?r2copyZ_copy_internals)rrrrrrs  z _annotate_columns..cloner)rrrrrrs rc@s,eZdZUded<ded<ded<ded<ded <d ed <d ed <d ed<ded<ded<ded<ded<ded<ddddddddddddd ddddddddddddddddd d!d"Zd#d$d%d&Zd#d$d'd(Zd#d$d)d*Zedd$d+d,Z edd$d-d.Z e j dd$d/d0Z d1d2dd3d4d5Ze j dd$d6d7Ze j dd$d8d9Zd#d$d:d;Zd#d$dd?Zdd$d@dAZdd$dBdCZd#d$dDdEZd#d$dFdGZdHdd#dIdJdKZd#d$dLdMZd#d$dNdOZd#d$dPdQZd#d$dRdSZd#d$dTdUZd#d$dVdWZd#d$dXdYZddd#dZd[d\Z d#d$d]d^Z!d_d`dadbdcZ"d#d$dddeZ#e$%Z&dfedg<d#d$dhdiZ'e j djd$dkdlZ(e j djd$dmdnZ)e j djd$dodpZ*d2djdqdrdsZ+dtdudjd3dvdwZ,e j dxd$dydzZ-dddddd|d}d~ddZ.ddddddZ/dS)rrprimaryjoin_initialrrrrrrrrrrr*rrjrrrrrrNFTcGsdSNTr)rrrrzJoinCondition.) rrrrrrrrrrrzOptional[_EquivalentColumnMap]rrzCallable[..., bool]rc Cs||_||_||_||_||_| |_||_||_||_| |_ | |_ | |_ ||_ | |_ ||_||_||jdk svt||||||||jd|jdk r||jd|||dSNTF)rrrrrrrrrrr _remote_siderrrr_determine_joinsrr,_sanitize_joins _annotate_fks_annotate_remote_annotate_local_annotate_parentmapper _setup_pairs_check_foreign_cols_determine_direction_check_remote_side _log_joins)rrrrrrrrrrrrrrrrrrrrrs< zJoinCondition.__init__rrcCs|jj}|d|j|j|d|j|j|d|jddd|jD|d|jddd|jpjgD|d |jdd d|jD|d |jdd d|j D|d |jddd|j D|d|j|j dS)Nz%s setup primary join %sz%s setup secondary join %sz%s synchronize pairs [%s],css|]\}}d||fVqdSz (%s => %s)Nrrlrrrrr sz+JoinCondition._log_joins..z#%s secondary synchronize pairs [%s]css|]\}}d||fVqdSrrrrrrr$ sz%s local/remote pairs [%s]css|]\}}d||fVqdS)z (%s / %s)Nrrrrrr, sz%s remote columns [%s]css|]}d|VqdSz%sNrrrMrrrr3 sz%s local columns [%s]css|]}d|VqdSrrrrrrr8 sz%s relationship direction %s) rloggerrrrjoinrrrrrr)rr2rrrr sF   zJoinCondition._log_joinscCs.t|jdd|_|jdk r*t|jdd|_dS)a_remove the parententity annotation from our join conditions which can leak in here based on some declarative patterns and maybe others. "parentmapper" is relied upon both by the ORM evaluator as well as the use case in _join_fixture_inh_selfref_w_entity that relies upon it being present, see :ticket:`3364`. )r proxy_keyvaluesN)rCrrrrrrr< s  zJoinCondition._sanitize_joinsc Csv|jdk r$|jdkr$td|jz|jp.d}|jdk r|jdkr\t|j|j|j|d|_|j dkrt|j |j|j |d|_ q|j |_ n,|j dkrt|j |j|j |d|_ n|j |_ Wntj k r}z:|jdk rt d|j|jf|nt d|j|W5d}~XYn^tjk rp}z<|jdk rNtd|j|jf|ntd|j|W5d}~XYnXdS)zDetermine the 'primaryjoin' and 'secondaryjoin' attributes, if not passed to the constructor already. This is based on analysis of the foreign key relationships between the parent and target mapped selectables. NzMProperty %s specified with secondary join condition but no secondary argument)Za_subsetra1Could not determine join condition between parent/child tables on relationship %s - there are no foreign keys linking these tables via secondary table '%s'. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify 'primaryjoin' and 'secondaryjoin' expressions.aCould not determine join condition between parent/child tables on relationship %s - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.alCould not determine join condition between parent/child tables on relationship %s - there are multiple foreign key paths linking the tables via secondary table '%s'. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference from the secondary table to each of the parent and child tables.a'Could not determine join condition between parent/child tables on relationship %s - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.)rrrrrrrGrrrrrrZNoForeignKeysErrorZAmbiguousForeignKeysError)rrZnfeZaferrrrN s                   zJoinCondition._determine_joinscCst|jddSNlocalr}r)rCrrrrrr sz%JoinCondition.primaryjoin_minus_localcCs|jdk stt|jddSr)rr,rCrrrrr sz'JoinCondition.secondaryjoin_minus_localcCsJ|jr(dddddd}t|ji|S|jr.replacerrN)_has_remote_annotationsr;replacement_traverser_has_foreign_annotationsrC)rr!rrrr s z(JoinCondition.primaryjoin_reverse_remoterhr)rrr|cCs&t|iD]}||jkr dSq dSr)r;iterater )rrrrMrrr_has_annotation s zJoinCondition._has_annotationcCs||jdSNrr&rrrrrr$ sz&JoinCondition._has_foreign_annotationscCs||jdSNr}r(rrrrr" sz%JoinCondition._has_remote_annotationscCs&|jr dS|jr|n|dS)zAnnotate the primaryjoin and secondaryjoin structures with 'foreign' annotations marking columns considered as foreign. N)r$r_annotate_from_fk_list_annotate_present_fksrrrrr s  zJoinCondition._annotate_fkscsHddddfdd }tji|_jdk rDtji|_dS)Nryrrrcs|jkr|ddiSdSNrT)rr2rrrrrcheck_fk s z6JoinCondition._annotate_from_fk_list..check_fk)r;r#rr)rr.rrrr* s z$JoinCondition._annotate_from_fk_listcs|jdk rt|jjntddddfdd dddfd d }t|jid |i|_|jdk rt|jid |i|_dS) NrzzOptional[ColumnElement[Any]])abr|csdt|tjr4t|tjr4||r&|S||r4|Sr`|krL|krL|S|kr`|kr`|SdSr)rr3ColumnZ references)r/r0) secondarycolsrr is_foreign s  z7JoinCondition._annotate_present_fks..is_foreignBinaryExpression[Any]rbinaryr|cst|jtjrt|jtjs dSd|jjkrd|jjkr|j|j}|dk r||jrn|jddi|_n||jr|jddi|_dSr,)rleftr4r@rightr comparer2)r6rM)r3rr visit_binary s&     z9JoinCondition._annotate_present_fks..visit_binaryr6) rr5rrrr;rlrrrr:r)r3r2rr+ s   z#JoinCondition._annotate_present_fkscs@|j|jddddfdd }t|jid|iS)zvReturn True if the join condition contains column comparisons where both columns are in both tables. Fr4rr5cs^|j|j}}t|tjrZt|tjrZ|jrZ|jrZ|jrZ|jrZddSr)r7r8rr8r?Zis_derived_fromtable)r6rfmtptresultrrr:A s      z;JoinCondition._refers_to_parent_table..visit_binaryr6)rrr;r1rr;rr>r_refers_to_parent_table8 s  z%JoinCondition._refers_to_parent_tablecCst|j|jS)z5Return True if parent/child tables have some overlap.)rHrrrrrr_tables_overlapQ szJoinCondition._tables_overlapcCsl|jr dS|jdk r|nJ|js*|jr4|n4|rN|dddn|r`| n| dS)zAnnotate the primaryjoin and secondaryjoin structures with 'remote' annotations marking columns considered as part of the 'remote' side. NcSs d|jkSr'r rNrrrrg rz0JoinCondition._annotate_remote..F) r"r_annotate_remote_secondaryrr_annotate_remote_from_argsrB_annotate_selfrefrC_annotate_remote_with_overlap%_annotate_remote_distinct_selectablesrrrrrX s     zJoinCondition._annotate_remotecs`|jdk st|jddddfdd }t|ji||_|jdk sJtt|ji||_dS)z^annotate 'remote' in primaryjoin, secondaryjoin when 'secondary' is present. Nryrrrcsj|r|ddiSdSNr}T)rrr2r-Zfixed_secondaryrrreplw s z6JoinCondition._annotate_remote_secondary..repl)rr,r;r#rrrrLrrKrrEn sz(JoinCondition._annotate_remote_secondaryz$Callable[[ColumnElement[Any]], bool])fnremote_side_givenr|cs2dddfdd }tjid|i_dS)zxannotate 'remote' in primaryjoin, secondaryjoin when the relationship is detected as self-referential. r4rr5csx|j|j}t|jtjrht|jtjrh|jrF|jddi|_|jrt|st|jddi|_n stdSrJ)r7r9r8rr8r?r2_warn_non_column_elements)r6ZequatedrNrOrrrr: s z5JoinCondition._annotate_selfref..visit_binaryr6N)r;rlr)rrNrOr:rrQrrG s  zJoinCondition._annotate_selfrefcsx|jr(|jrtddd|jDn|j|rL|fdddn(ddd d fd d }t|ji||_d S)zannotate 'remote' in primaryjoin, secondaryjoin when the 'remote_side' or '_local_remote_pairs' arguments are used. zTremote_side argument is redundant against more detailed _local_remote_side argument.cSsg|] \}}|qSrrrrrrrT sz.cs|kSrrrNrrrr rz:JoinCondition._annotate_remote_from_args..Tryrrrcs|tkr|ddiSdSrJ)rr2r-rRrrrL s z6JoinCondition._annotate_remote_from_args..replN) rrrrrBrGr;r#rrMrrRrrF sz(JoinCondition._annotate_remote_from_argscs`dddfdd }jdk o,jjjjk dddd fd d tjid |i_dS) zannotate 'remote' in primaryjoin, secondaryjoin when the parent/child tables have some set of tables in common, though is not a fully self-referential relationship. r4rr5cs0|j|j\|_|_|j|j\|_|_dSrr7r8)r6)proc_left_rightrrr: s zAJoinCondition._annotate_remote_with_overlap..visit_binaryNrzz-Tuple[ColumnElement[Any], ColumnElement[Any]])r7r8r|cst|tjrDt|tjrDjj|rjj|r|ddi}nXrl|j dj j krl|ddi}n0r|j dj j kr|ddi}n ||fS)Nr}Tr) rr8r?rrrrr2r rrrrPrS)check_entitiesrrrrT s, zDJoinCondition._annotate_remote_with_overlap..proc_left_rightr6)rrrr;rlrr;r)rUrTrrrH s z+JoinCondition._annotate_remote_with_overlapcs,ddddfdd }tji|_dS)z}annotate 'remote' in primaryjoin, secondaryjoin when the parent/child tables are entirely separate. ryrrrcs<jj|r8jj|r*jj|r8|ddiSdSrJ)rrrrrr2r-rrrrL s  zAJoinCondition._annotate_remote_distinct_selectables..replNr;r#rrMrrrrI s z3JoinCondition._annotate_remote_distinct_selectablescCstd|jdS)NzNon-simple column elements in primary join condition for property %s - consider using remote() annotations to mark the remote side.)r5rrrrrrrP s z'JoinCondition._warn_non_column_elementscsj||jdrdS|jr0tdd|jDnt|jjddddfd d }t|ji||_dS) aCAnnotate the primaryjoin and secondaryjoin structures with 'local' annotations. This annotates all column elements found simultaneously in the parent table and the join condition that don't have a 'remote' annotation set up from _annotate_remote() or user-defined. rNcSsg|] \}}|qSrrrrrrrT sz1JoinCondition._annotate_local..ryrrrcs$d|jkr |kr |ddiSdS)Nr}rT)r r2r-Z local_siderrlocals_ sz.JoinCondition._annotate_local..locals_) r&rrr5rrrr;r#)rrXrrWrr  s zJoinCondition._annotate_localcs,ddddfdd }tji|_dS)Nryrrrcs<d|jkr|djjiSd|jkr8|djjiSdS)Nr}rr)r r2rrrr-rrrparentmappers_) s   z.parentmappers_rV)rrYrrrr ( s z$JoinCondition._annotate_parentmappercCs^|jstd|jfn@t|jj|j j}|jD] \}}||kr8t d|fq8dS)NaRelationship %s could not determine any unambiguous local/remote column pairs based on join condition and remote_side arguments. Consider using the remote() annotation to accurately mark those elements of the join condition that are on the remote side of the relationship.zExpression %s is marked as 'remote', but these column(s) are local to the local side. The remote() annotation is needed only for a self-referential relationship where both sides of the relationship refer to the same tables.) rrrrr5rrr differencerr)rZ not_target_Zrmtrrrr4 s$ z JoinCondition._check_remote_side)rGprimaryr|cCsd}||d}t|}|r(t|j}n t|j}|jr<|sF|jsJ|rJdS|jr|r|sd|rbdpdd||jf}|d7}t|n*d|rdpd||jf}|d 7}t|dS) zHCheck the foreign key columns collected and emit error messages.FrNzCould not locate any simple equality expressions involving locally mapped foreign key columns for %s join condition '%s' on relationship %s.r\ra Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation. To allow comparison operators other than '==', the relationship can be marked as viewonly=True.z`Could not locate any relevant foreign key columns for %s join condition '%s' on relationship %s.z Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation.)_gather_columns_with_annotationrrrrrrr)rrGr\Zcan_syncZ foreign_colsZ has_foreignerrrrrr P sR       z!JoinCondition._check_foreign_colscCs|jdk rt|_nt|jj}t|jj}||j }||j }|r|r| |j dd}dd| |j dD}|r|r|j |j }||}||}|r|st|_q|r|st|_qtd|jn(|rt|_n|rt|_ntd|jdS)z[Determine if this relationship is one to many, many to one, many to many. Nr}rcSsh|]}d|jkr|qS)r}rDrrrrr s z5JoinCondition._determine_direction..aDCan't determine relationship direction for relationship '%s' - foreign key columns within the join condition are present in both the parent and the child's mapped tables. Ensure that only those columns referring to a parent column are marked as foreign, either via the foreign() annotation or via the foreign_keys argument.zCan't determine relationship direction for relationship '%s' - foreign key columns are present in neither the parent nor the child's mapped tables)rr&rr5rrrrrrr]rrrrZr(r'rrr)rZ parentcolsZ targetcolsZ onetomany_fkZ manytoone_fkZonetomany_localZmanytoone_localZ self_equatedrrrr  sT        z"JoinCondition._determine_direction_ColumnPairIterable_MutableColumnPairs)rr|cCsdd|DS)zprovide deannotation for the various lists of pairs, so that using them in hashes doesn't incur high-overhead __eq__() comparisons against original columns mapped. cSs g|]\}}||fqSrZ _deannotaterQrrrrT sz3JoinCondition._deannotate_pairs..r)rrrrr_deannotate_pairs s zJoinCondition._deannotate_pairscsg}tgg}ddddfdd }j|fj|ffD]\}}|dkrPq>|||q>_|_|_dS)Nrrbr)joincondrr|cs*dddddfdd }t||dS)Nr4rzr)r6r7r8r|csd|jkr.d|jkr.|r.||fn,d|jkrZd|jkrZ|rZ||f|jtjkr||rd|jkr||fnd|jkr||fdS)Nr}r)r rroperatorr9eqr)r6r7r8)rlrprrrr: s,  z.go..visit_binaryrI)rerr:rhr)rrgo sz&JoinCondition._setup_pairs..go)r5Z OrderedSetrrrdrrr)rZ sync_pairsZsecondary_sync_pairsrjrerrrirr  s      zJoinCondition._setup_pairszwweakref.WeakKeyDictionary[ColumnElement[Any], weakref.WeakKeyDictionary[RelationshipProperty[Any], ColumnElement[Any]]]_track_overlapping_sync_targetsc s|js dSdd|jDdd|jDD]b\}|jkrVt|j|i|j<q*g}|j}|D]\}}|jj sl||jj krl|j |jj krl|jj |j krld|jj krld|j krl|jj |j sl|jj|jsl|jj |jsl|jj|j sl|jj |j ks|jj |j sl|||fql|r~tjd|j|dtfdd|Dd td d|D|jfd d ||j|j<q*dS) NcSsg|]\}}||fqSrrrfrom_to_rrrrT5 szDJoinCondition._warn_for_conflicting_sync_targets..cSsg|]\}}||fqSrrrlrrrrT7 sz__*arelationship '%s' will copy column %s to column %s, which conflicts with relationship(s): %s. If this is not the intention, consider if these relationships should be linked with back_populates, or if viewonly=True should be applied to one or more if they are read-only. For the less common case that foreign key constraints are partially overlapping, the orm.foreign() annotation can be used to isolate the columns that should be written towards. To silence this warning, add the parameter 'overlaps="%s"' to the '%s' relationship.z, c3s |]\}}d||fVqdS)z'%s' (copies %s to %s)Nr)rprfr_rnrrrv szCJoinCondition._warn_for_conflicting_sync_targets..rcss|]\}}|jVqdSrr)rrofrrrrr{ sZqzyxr)rrrrkweakrefWeakKeyDictionaryrrrZ_dispose_calledrrrrZ is_siblingrrr5rrsorted)rrmZ other_propsZ prop_to_fromrorprrqrr, st           z0JoinCondition._warn_for_conflicting_sync_targetsrcCs |dSr)_gather_join_annotationsrrrrr szJoinCondition.remote_columnscCs |dS)Nrrwrrrrr szJoinCondition.local_columnscCs |dSr'rwrrrrr sz!JoinCondition.foreign_key_columns)rr|cCs>t||j|}|jdk r0|||j|dd|DS)NcSsh|] }|qSrrcrrrrr` sz9JoinCondition._gather_join_annotations..)rr]rrr)rrsrrrrx s  z&JoinCondition._gather_join_annotationsrzz Iterable[str]cs"t|fddt|iDS)Ncs&h|]}|jrttt|qSr)issubsetr rr@rrZannotation_setrrr` s z@JoinCondition._gather_columns_with_annotation..)rr;r%)rrrrr{rr] s  z-JoinCondition._gather_columns_with_annotationzFrozenSet[ColumnElement[Any]]cCs0|jdk r&ttjdd|jjDStjSdS)NcSsg|] }|jqSr)Z proxy_setr_rrrrT sz8JoinCondition._secondary_lineage_set..)r frozenset itertoolschainrr5 EMPTY_SETrrrr_secondary_lineage_set s  z$JoinCondition._secondary_lineage_setrrztTuple[ColumnElement[bool], Optional[ColumnElement[bool]], Optional[FromClause], Optional[ClauseAdapter], FromClause])rr(rr6rr|c sjt|ddi}jjj}}}|dk rF|dk r>||@}n||@}|rddddfdd tfd d |D}|dk r|tj|@}n|tj|@}|rX|dk r|jdd }t|t d } t|j d  | } |dk rt|t d  t|j d } | |}n4t|t j d} |dk r8| t|tj dd} | |}| pN| } d| _nd} |||| |fS)a7Given a source and destination selectable, create a join between them. This takes into account aliasing the join clause to reference the appropriate corresponding columns in the target objects, as well as the extra child criterion, equivalent column sets, etc. r*TNrerd)rrr|csB|jdd}|jjk r:|jjk r:|jkr:t||S|SdS)anote unrelated columns in the "extra criteria" as either should be adapted or not adapted, even though they are not part of our "local" or "remote" side. see #9779 for this case, as well as #11010 for a follow up rN)r rrrrrr>)rrZparentmapper_for_elementrrrmark_exclude_cols s    z5JoinCondition.join_targets..mark_exclude_colsc3s |]}t|ddidVqdS)should_not_adaptT)Zannotate_callableNrA)rr)rrrr s z-JoinCondition.join_targets..)Zflat) exclude_fn) equivalents)rr)rDrrrrr4rr/rF_local_col_excluderr~rr1_remote_col_excluder) rrr(rr6rrrrZprimary_aliasizerZsecondary_aliasizerrr)rrrr s          zJoinCondition.join_targetszgTuple[ColumnElement[bool], Dict[str, ColumnElement[Any]], Dict[ColumnElement[Any], ColumnElement[Any]]])rmr|c s ii}|jdk rLtt|jD]"\}}|||f|||<q&n6sj|jD]\}}|||<qVn|jD]\}}|||<qpddddfdd }|j}|jdksst|i|}|jdk r|j}rt|i|}t ||}fddD}|||fS) NrzrzOptional[BindParameter[Any]]rcsXsd|jks,rTr|ks,sTd|jkrT|krLtjdd|jdd|<|SdS)Nrr}T)rErF)r r4rHrIr-bindsZ has_secondarylookuprmrr col_to_bindP s. z5JoinCondition.create_lazy_clause..col_to_bindcsi|]}|j|qSrrrr)rrr p sz4JoinCondition.create_lazy_clause..) r collections defaultdictlistrrrr;r#r4r) rrmZequated_columnsrrrZ lazywhererrbrrrcreate_lazy_clause: s@       z JoinCondition.create_lazy_clause)Nr)F)0rrrrrrrrrrrr5rrr&r$r"rr*r+rBrCrrErGrFrHrIrPr r rr r rdr rtrurkrrrrrxr]rrrrrrrrs  05&_$2!1 DR 9 V   rc@s2eZdZdZdZddddZdddd d Zd S) _ColInAnnotationszSerializable object that tests for names in c._annotations. TODO: does this need to be serializable anymore? can we find what the use case was for that? )namesrcGst||_dSr)r|r)rrrrrr sz_ColInAnnotations.__init__rhr)rr|cCst|j|jSr)rrrr )rrrrr__call__ sz_ColInAnnotations.__call__N)rrrrrrrrrrrru srrrc@seZdZdZdZdS) RelationshipaDescribes an object property that holds a single item or list of items that correspond to a related database table. Public constructor is the :func:`_orm.relationship` function. .. seealso:: :ref:`relationship_config_toplevel` .. versionchanged:: 2.0 Added :class:`_orm.Relationship` as a Declarative compatible subclass for :class:`_orm.RelationshipProperty`. TN)rrrrrrrrrr src@s&eZdZdZdZeddddZdS)_RelationshipDeclaredz>Relationship subclass used implicitly for declarative mapping.TrrcCsdS)Nrr)rrrr_mapper_property_name sz+_RelationshipDeclared._mapper_property_nameN)rrrrr classmethodrrrrrr sr)r __future__rrr dataclassesr6rr}rrrrrrrr r r r r rrrrrrrrrrtrrZ_typingrrbaserrrrr r!r"r#Z interfacesr$r%r&r'r(r)r*r+r5r,r-r.r0rr1r2r3r4Z inspectionr7r8r9r:r;Z sql._typingr<r=Zsql.annotationr>Z sql.elementsr?r@Zsql.utilrBrCrDrErFrGrHrJZ util.typingrKrLrM TYPE_CHECKINGrNrOrPrQrRrSrTrUZ clsregistryrVrWZ decl_baserXrrYrrZqueryr[ryr\rCr]Z strategiesr^r_r`rarbrcrdrerfrgrhZ sql.schemariZsql.selectablerjrkrlrmrorprqrrrZ_RelationshipArgumentTyperrZ"_RelationshipJoinConditionArgumentZ_RelationshipSecondaryArgumentrZORMBackrefArgumentZ DMLColumnRoleZ_ORMColCollectionElementZ_ORMColCollectionArgumentrxryrarrbr}r dataclassrrrZ class_loggerZ Identifiedrrrrrrrrrrrrs                                                                                                                     /