idTrddZddlmZddlmZddlmZddlmZddlmZddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlmZGddeZejddGddeZejddGddeZejddGddeZejddejddGddeZdS)zDescriptor properties are more "auxiliary" properties that exist as configurational elements, but don't participate as actively in the load/persist ORM loop. ) attributes) properties)query)MapperProperty)PropComparator) _none_set)event)exc)schema)sql)util) expressionc eZdZdZdZdZdZdS)DescriptorPropertyzO:class:`.MapperProperty` which proxies access to a user-defined descriptor.NFcGfddt}j7tjjd}|r|_j&fd}fd}fd}t |||_tjjj jjjfdj }|j|_ j j|dS) NcpeZdZdZdZdZefdZdZe dre j ffd Z dSdS)7DescriptorProperty.instrument_class.._ProxyImplFTcjSN) uses_objectsselfprops T/opt/cloudlinux/venv/lib/python3.11/site-packages/sqlalchemy/orm/descriptor_props.pyrzDDescriptorProperty.instrument_class.._ProxyImpl.uses_objects,s ((c||_dSrkey)rrs r__init__z@DescriptorProperty.instrument_class.._ProxyImpl.__init__0s r get_historyc2|||Sr)r!)rstatedict_passivers rr!zCDescriptorProperty.instrument_class.._ProxyImpl.get_history5s ++E5'BBBrN) __name__ __module__ __qualname__accepts_scalar_loaderexpire_missing collectionpropertyrr hasattrr PASSIVE_OFFr!)rsr _ProxyImplr's$) !!NJ  ) ) ) )X )   wt]++ C1;0FCCCCCCCC C Crr/c4t|j|dSr)setattrname)objvaluers rfsetz1DescriptorProperty.instrument_class..fsetAsTY.....rc2t|jdSr)delattrr2r3rs rfdelz1DescriptorProperty.instrument_class..fdelDsTY'''''rc.t|jSr)getattrr2r8s rfgetz1DescriptorProperty.instrument_class..fgetGssDI...r)r<r5r9c.Sr)_comparator_factory)mapperrsrz5DescriptorProperty.instrument_class..PsD,,V44r)docoriginal_property)object descriptorr;class_r_is_userland_descriptorr,rcreate_proxied_attributeparentrAimpl class_managerinstrument_attribute) rr?r/descr5r9r< proxy_attrrs `` @rinstrument_classz#DescriptorProperty.instrument_class$sq C C C C C C C C C C& ? "6=$(D99D--d33 '"& ? " / / / / / ( ( ( ( ( / / / / /'Dt$GGGDOIZ8II K  H O 4 4 4 4 4"    %*TX.. 11$(JGGGGGr)r&r'r(__doc__rArrNrrrrs>   CL1H1H1H1H1Hrrzsqlalchemy.orm.propertiesT) add_to_allc^eZdZdZejdfdZfdZdZe Z dZ ej dZ ej d Zed Zd Zd Zej d ZejfdZdZGddejZGddeZdZxZS)CompositePropertyzDefines a "composite" mapped attribute, representing a collection of columns as one attribute. :class:`.CompositeProperty` is constructed using the :func:`.composite` function. .. seealso:: :ref:`mapper_composite` )0.7z:class:`.AttributeExtension` is deprecated in favor of the :class:`.AttributeEvents` listener interface. The :paramref:`.composite.extension` parameter will be removed in a future release.) extensionctt|||_||_|dd|_|dd|_|dd|_| d|j j |_ d|vr| d|_ tj||dS)aQReturn a composite column-based property for use with a Mapper. See the mapping documentation section :ref:`mapper_composite` for a full usage example. The :class:`.MapperProperty` returned by :func:`.composite` is the :class:`.CompositeProperty`. :param class\_: The "composite type" class, or any classmethod or callable which will produce a new instance of the composite object given the column values in order. :param \*cols: List of Column objects to be mapped. :param active_history=False: When ``True``, indicates that the "previous" value for a scalar attribute should be loaded when replaced, if not already loaded. See the same flag on :func:`.column_property`. :param group: A group name for this property when marked as deferred. :param deferred: When True, the column property is "deferred", meaning that it does not load immediately, and is instead loaded when the attribute is first accessed on an instance. See also :func:`~sqlalchemy.orm.deferred`. :param comparator_factory: a class which extends :class:`.CompositeProperty.Comparator` which provides custom SQL clause generation for comparison operations. :param doc: optional string that will be applied as the doc on the class-bound descriptor. :param info: Optional data dictionary which will be populated into the :attr:`.MapperProperty.info` attribute of this object. :param extension: an :class:`.AttributeExtension` instance, or list of extensions, which will be prepended to the list of attribute listeners for the resulting descriptor placed on the class. active_historyFdeferredgroupNcomparator_factoryinfo)superrSr attrscomposite_classgetrWrXrYpop __class__ ComparatorrZr[rset_creation_order_create_descriptor)rrEr]kwargsras rr zCompositeProperty.__init__fst &&//111 %$jj)95AA :u55 ZZ.. "(** $.";# #  V   6**DI %%% !!!!!rctt|||dSr)r\rSrN_setup_event_handlers)rr?ras rrNz"CompositeProperty.instrument_classs: &&77??? ""$$$$$rc.|dS)zInitialization which occurs after the :class:`.CompositeProperty` has been associated with its parent mapper. N)_setup_arguments_on_columnsrs rdo_initzCompositeProperty.do_inits ((*****rcRfd}fd}fd}t|||_dS)ztCreate the Python descriptor that will serve as the access point on instances of the mapped class. ctj}tj}j|vrufdjD}j|vrY|jt j|s>j||j<|jj |j jg| jdS)Nc0g|]}t|SrP)r;).0rinstances r zFCompositeProperty._create_descriptor..fget..s0/2GHc**r) r instance_dictinstance_stater_attribute_keysr issupersetr^managerdispatchrefresh_COMPOSITE_FGETr_)rpr$r#valuesrs` rr<z2CompositeProperty._create_descriptor..fgets,X66E-h77Exu$$6:6J85((I)1Ef1M1M)&:d&:F&CE$(OM*22t3dhZ99TXt,, ,rctj|}tj|}|jj}|jtj}|jjD]}|||||j }||j<|j D]}t||ddStj | D]\}}t|||dSr)rrrrsrvrr_NO_VALUErwsetrIrtr1zip__composite_values__) rpr4r$r#attrpreviousfnrrs rr5z2CompositeProperty._create_descriptor..fsets ,X66E-h77E=*Dyy:+>??Hm' > >5%49==#E$(O}/11CHc4000011#&(%*D*D*F*F##22JCHc5111122rc>tj|}tj|}|jtj}|jj}|j|||j j D]}t||ddSr) rrsrrr`rr|rvrwremoverIrtr1)rpr#r$rrrrs rr9z2CompositeProperty._create_descriptor..fdels-h77E,X66Eyy:+>??H=*D M $) < < <+ - -#t,,,, - -rN)r,rD)rr<r5r9s` rrdz$CompositeProperty._create_descriptorsg  - - - - -6 2 2 2 2 2" - - - - -#4t44rc*fdjDS)NcNg|]!}tjj|j"SrP)r;rHrErrorrs rrqz:CompositeProperty._comparable_elements..s*MMM$ *DH55MMMrpropsrjs`r_comparable_elementsz&CompositeProperty._comparable_elementssMMMM$*MMMMrcxg}|jD]}t|tr|j|d}nft|t jr|jj|}n9t|tj r|j }ntj d|| ||S)NF)_configure_mapperszYComposite expects Column objects or mapped attributes/attribute names as arguments, got: )r] isinstancestrrH get_propertyr Column_columntopropertyrInstrumentedAttributer,sa_exc ArgumentErrorappend)rrrrs rrzCompositeProperty.propssJ  D$$$ {///OOD&-00 {4T:D*"BCC }**t LL     rc$d|jDS)NcFg|]}t|tj|SrP)rr r)roas rrqz-CompositeProperty.columns..s)FFFaAv})E)EFFFFr)r]rjs rcolumnszCompositeProperty.columnssFF4:FFFFrc~|jD]4}|j|_|jr|j|_d|_|j|_5dS)zwPropagate configuration arguments made on this composite to the target columns, for those that apply. ))rXT) instrumentTN)rrWrX strategy_keyrYrs rriz-CompositeProperty._setup_arguments_on_columnssQ J $ $D"&"5D } O $  $N!DJJ  $ $rcffd}fd}fdfd}fd}tjjd|dtjjd |dtjjd |dd tjjd |dd tjjd |dd dS)z>Establish events that populate/expire the composite attribute.c&||dddS)NF is_refreshrP)r#context_load_refresh_handlers r load_handlerz=CompositeProperty._setup_event_handlers..load_handler$s# ! !%$5 I I I I I Irc|r3jhj|r|||ddSdS)NTr)runionrt intersection)r#rto_loadrrs rrefresh_handlerz@CompositeProperty._setup_event_handlers..refresh_handler'sg P   !566l7## P&%eWg$OOOOOO P Prcj}|r |jur j|vrdSjD] }||vrdS jfdjD|j<dS)Nc*g|]}j|SrP)dict)rorr#s rrqzZCompositeProperty._setup_event_handlers.._load_refresh_handler..HsBBBc%*S/BBBr)rryrrtr^)r#rrrr$krs` rrzFCompositeProperty._setup_event_handlers.._load_refresh_handler/sJE ")T-A"A"A(e## )  E>>FF"3d2BBBBT-ABBBE$(OOOrc|'tj|r"|jjddSdSr)r}rtrrr`r)r#keysrs rexpire_handlerz?CompositeProperty._setup_event_handlers..expire_handlerKsJ|s4#788EEdKK| tx.....|rcH|jjddS)zAfter an insert or update, some columns may be expired due to server side defaults, or re-populated due to client side defaults. Pop out the composite value here so that it recreates. N)rr`r)r? connectionr#rs rinsert_update_handlerzFCompositeProperty._setup_event_handlers..insert_update_handlerOs# JNN48T * * * * *r after_insertT)raw after_updateload)r propagaterxexpireN)r listenrH)rrrrrrs` @rrgz'CompositeProperty._setup_event_handlers!sa J J J J J P P P P P P     8 / / / / / + + + + +  K)>D      K)>D      K44      KO      K>tt      rc$d|jDS)Ncg|] }|j SrPr)rors rrqz5CompositeProperty._attribute_keys..ms000T000rrrjs rrtz!CompositeProperty._attribute_keysks00TZ0000rc*g}g}d}|jD]}|j}|j|j||} | rd}| } | r|| n|d| j r|| j |d|r(tj |j |gd|j |gStj d|j |gdS)z>Provided for userland code that uses attributes.get_history().FTNrP) rrrvrIr! has_changes non_deletedextendrdeletedrHistoryr^) rr#r$r%addedr has_historyrrhistrs rr!zCompositeProperty.get_historyos? J % %D(C=%*66ueDDD!! #" **,,K # [)))) T"""| %t|,,,,t$$$$  N%%%u-.%%w/0  %b+?4+?+G*H"MM Mrc.|||SrrZrr?s rr>z%CompositeProperty._comparator_factory&&tV444rc$eZdZfdZdZxZS)!CompositeProperty.CompositeBundlecl||_ttj|j|jg|RdSr)r,r\rSCompositeBundler r)r property_exprras rr z*CompositeProperty.CompositeBundle.__init__sK%DM CE#3T : : C   $      rcfd}|S)Nc<jjfdDS)Nc&g|] }|SrPrP)roprocrows rrqzXCompositeProperty.CompositeBundle.create_row_processor..proc..s!222Ddd3ii222r)r,r^)rprocsrs`rrzDCompositeProperty.CompositeBundle.create_row_processor..procs/4t}42222E222rrP)rrrlabelsrs` ` rcreate_row_processorz6CompositeProperty.CompositeBundle.create_row_processors)       Kr)r&r'r(r r __classcell__ras@rrrsG             rrcjeZdZdZdZedZdZdZdZ e j dZ dZ d ZdS) CompositeProperty.ComparatoraProduce boolean, comparison, and other operators for :class:`.CompositeProperty` attributes. See the example in :ref:`composite_operations` for an overview of usage , as well as the documentation for :class:`.PropComparator`. .. seealso:: :class:`.PropComparator` :class:`.ColumnOperators` :ref:`types_operators` :attr:`.TypeEngine.comparator_factory` Nc*|Sr)__clause_element__rjs rclausesz$CompositeProperty.Comparator.clausess**,, ,rc.tj|jddiS)NrYF)r ClauseListrrjs rrz/CompositeProperty.Comparator.__clause_element__s%("7 rcft|j|Sr)rSrrrrjs r_query_clause_elementz2CompositeProperty.Comparator._query_clause_elements-$44 42244 rc|d|jjD}nNt||jjr|}nt jd|jd|t|j|S)Ncg|]}dSrrP)rors rrqzDCompositeProperty.Comparator._bulk_update_tuples..sDDD3$DDDrz!Can't UPDATE composite attribute z to ) rrtrr^rrrr~r)rr4rzs r_bulk_update_tuplesz0CompositeProperty.Comparator._bulk_update_tupless}DD$)*CDDDE49#<== 3355**yyy%%) t0&99 9rcZjrfdjjDSjjS)NcNg|]!}tjj|j"SrP)r;_adapt_to_entityentityrrs rrqzECompositeProperty.Comparator._comparable_elements..s;D18$(CCr)rrrrjs`rrz1CompositeProperty.Comparator._comparable_elementssK$ 6 $ > y55rc|dgtjjz}n|}dt jj|D}jrfd|D}t j|S)Nc g|] \}}||k SrPrP)rorbs rrqz7CompositeProperty.Comparator.__eq__..s-1aQrc:g|]}|SrP)adapter)roxrs rrqz7CompositeProperty.Comparator.__eq__..s#DDD1t||ADDDr)lenrrrr~rr and_)rotherrz comparisonss` r__eq__z#CompositeProperty.Comparator.__eq__s}#di&D"E"EE3355#&ty'Ev#N#NK$ EDDDD DDD 8[) )rcPtj||Sr)r not_r)rrs r__ne__z#CompositeProperty.Comparator.__ne__s8DKK..// /r)r&r'r(rO__hash__r,rrrrrmemoized_propertyrrrrPrrrbrs  $  - -  -        : : :   6 6  6 * * * 0 0 0 0 0rrbcTt|jjjdz|jzS)N.)rrHrEr&rrjs r__str__zCompositeProperty.__str__s$4;%.//#5@@r)r&r'r(rOrdeprecated_paramsr rNrkrCryrdrrrr,rrirgrtrr.r!r>rBundlerrrbrrrs@rrSrSXs  T ?"?"?"?"?"B%%%%%+++fhhO;5;5;5z NNN $GGXG $ $ $F F F T 1111;0FNNNN@555     %,   G0G0G0G0G0^G0G0G0RAAAAAAArrSc(eZdZdZdZfdZxZS)ConcreteInheritedPropertya4A 'do nothing' :class:`.MapperProperty` that disables an attribute on a concrete subclass that is only present on the inherited mapper, not the concrete classes' mapper. Cases where this occurs include: * When the superclass mapper is mapped against a "polymorphic union", which includes all attributes from all subclasses. * When a relationship() is configured on an inherited mapper, but not on the subclass mapper. Concrete mappers require that relationship() is configured explicitly on each subclass. cd}|jD]2}|j|j}t |t s |j}n3|Sr)rHiterate_to_root_propsrrrrZ)rr?comparator_callablemps rr>z-ConcreteInheritedProperty._comparator_factorysa",,..  A"Aa!:;; &'&:# #"rcttfdGfddt}|_dS)Nc Ttdjdjdjd)Nz Concrete z does not implement attribute z9 at the instance level. Add this property explicitly to r)AttributeErrorrHrrjsrwarnz0ConcreteInheritedProperty.__init__..warn s7 .;;;$+++7 rc0eZdZfdZfdZfdZdS)DConcreteInheritedProperty.__init__..NoninheritedConcretePropcdSrrP)sr3r4r s r__set__zLConcreteInheritedProperty.__init__..NoninheritedConcreteProp.__set__rcdSrrP)r r3r s r __delete__zOConcreteInheritedProperty.__init__..NoninheritedConcreteProp.__delete__rrc.|jSdSr)rD)r r3ownerrr s r__get__zLConcreteInheritedProperty.__init__..NoninheritedConcreteProp.__get__s;?*rN)r&r'r(rrr)rr srNoninheritedConcretePropr se                  rr)r\rr rCrD)rrr ras` @rr z"ConcreteInheritedProperty.__init__ s '..77999             v   3244r)r&r'r(rOr>r rrs@rrrsQ ###555555555rrcreZdZ dfd ZedZejdZdZ dZ dZ xZ S) SynonymPropertyNctt|||_||_||_||_|p |r|jpd|_|r||_ tj |dS)aDenote an attribute name as a synonym to a mapped property, in that the attribute will mirror the value and expression behavior of another attribute. e.g.:: class MyClass(Base): __tablename__ = 'my_table' id = Column(Integer, primary_key=True) job_status = Column(String(50)) status = synonym("job_status") :param name: the name of the existing mapped property. This can refer to the string name ORM-mapped attribute configured on the class, including column-bound attributes and relationships. :param descriptor: a Python :term:`descriptor` that will be used as a getter (and potentially a setter) when this attribute is accessed at the instance level. :param map_column: **For classical mappings and mappings against an existing Table object only**. if ``True``, the :func:`.synonym` construct will locate the :class:`_schema.Column` object upon the mapped table that would normally be associated with the attribute name of this synonym, and produce a new :class:`.ColumnProperty` that instead maps this :class:`_schema.Column` to the alternate name given as the "name" argument of the synonym; in this way, the usual step of redefining the mapping of the :class:`_schema.Column` to be under a different name is unnecessary. This is usually intended to be used when a :class:`_schema.Column` is to be replaced with an attribute that also uses a descriptor, that is, in conjunction with the :paramref:`.synonym.descriptor` parameter:: my_table = Table( "my_table", metadata, Column('id', Integer, primary_key=True), Column('job_status', String(50)) ) class MyClass(object): @property def _job_status_descriptor(self): return "Status: %s" % self._job_status mapper( MyClass, my_table, properties={ "job_status": synonym( "_job_status", map_column=True, descriptor=MyClass._job_status_descriptor) } ) Above, the attribute named ``_job_status`` is automatically mapped to the ``job_status`` column:: >>> j1 = MyClass() >>> j1._job_status = "employed" >>> j1.job_status Status: employed When using Declarative, in order to provide a descriptor in conjunction with a synonym, use the :func:`sqlalchemy.ext.declarative.synonym_for` helper. However, note that the :ref:`hybrid properties ` feature should usually be preferred, particularly when redefining attribute behavior. :param info: Optional data dictionary which will be populated into the :attr:`.InspectionAttr.info` attribute of this object. .. versionadded:: 1.0.0 :param comparator_factory: A subclass of :class:`.PropComparator` that will provide custom comparison behavior at the SQL expression level. .. note:: For the use case of providing an attribute which redefines both Python-level and SQL-expression level behavior of an attribute, please refer to the Hybrid attribute introduced at :ref:`mapper_hybrids` for a more effective technique. .. seealso:: :ref:`synonyms` - Overview of synonyms :func:`.synonym_for` - a helper oriented towards Declarative :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an updated approach to augmenting attribute behavior more flexibly than can be achieved with synonyms. N) r\rr r2 map_columnrDrZrOrAr[rrc)rr2rrDrZrAr[ras rr zSynonymProperty.__init__&s~` ot$$--/// $$"4E:<**<E  DI %%%%%rcTt|jj|jjjSr)r;rHrEr2rIrrjs rrzSynonymProperty.uses_objectsst{)4955:GGrct|jj|j}t |drt |jts1tj d|jjj d|jd||jS)Nr,zsynonym() attribute "rz+" only supports ORM mapped attributes, got ) r;rHrEr2r-rr,rrInvalidRequestErrorr&)rrs r_proxied_propertyz!SynonymProperty._proxied_propertyst{)4955tZ((  M>1 1  ,,;%... 44A  }rc||j}|jr|||}n|||}|Sr)rrZ)rr?rcomps rr>z#SynonymProperty._comparator_factorysF%  " 9**488DD**488D rcdt|jj|j}|jj|i|Sr)r;rHrEr2rIr!)rargkwrs rr!zSynonymProperty.get_historys2t{)4955$ty$c0R000rc X|jr|j|jjvr2t jd|jd|jjd|jd|jj|j|jvrd|j|jj|jj|jkr4t jd|jd|jd|jd|jtj |jj|j}| |j||d |j|_ ||_ dS) NzCan't compile synonym 'z': no column on table 'z ' named ''z'Can't call map_column=True for synonym =z4, a ColumnProperty already exists keyed to the name z for column T)init setparent)rrpersist_selectablecrrr2 descriptionrrColumnProperty_configure_property_mapped_by_synonymrH)rrHr&rs r set_parentzSynonymProperty.set_parentsI ? ,xv8:::** 1=== )+DH5+,,,-/99 **xxxDIIItxxA ))+DH5A  & &ty!$$ & O O O#'8A  r)NNNNN) r&r'r(r r,rrrrr>r!r.rrs@rrr$s   z&z&z&z&z&z&xHHXH     111!!!!!!!rrrTz:func:`.comparable_property` is deprecated and will be removed in a future release. Please refer to the :mod:`~sqlalchemy.ext.hybrid` extension.c,eZdZdZ dfd ZdZxZS)ComparablePropertyz;Instruments a Python property for use in query expressions.Nctt|||_||_|p |r|jpd|_|r||_tj |dS)a Provides a method of applying a :class:`.PropComparator` to any Python descriptor attribute. Allows any Python descriptor to behave like a SQL-enabled attribute when used at the class level in queries, allowing redefinition of expression operator behavior. In the example below we redefine :meth:`.PropComparator.operate` to wrap both sides of an expression in ``func.lower()`` to produce case-insensitive comparison:: from sqlalchemy.orm import comparable_property from sqlalchemy.orm.interfaces import PropComparator from sqlalchemy.sql import func from sqlalchemy import Integer, String, Column from sqlalchemy.ext.declarative import declarative_base class CaseInsensitiveComparator(PropComparator): def __clause_element__(self): return self.prop def operate(self, op, other): return op( func.lower(self.__clause_element__()), func.lower(other) ) Base = declarative_base() class SearchWord(Base): __tablename__ = 'search_word' id = Column(Integer, primary_key=True) word = Column(String) word_insensitive = comparable_property(lambda prop, mapper: CaseInsensitiveComparator( mapper.c.word, mapper) ) A mapping like the above allows the ``word_insensitive`` attribute to render an expression like:: >>> print(SearchWord.word_insensitive == "Trucks") lower(search_word.word) = lower(:lower_1) :param comparator_factory: A PropComparator subclass or factory that defines operator behavior for this property. :param descriptor: Optional when used in a ``properties={}`` declaration. The Python descriptor or property to layer comparison behavior on top of. The like-named descriptor will be automatically retrieved from the mapped class if left blank in a ``properties`` declaration. :param info: Optional data dictionary which will be populated into the :attr:`.InspectionAttr.info` attribute of this object. .. versionadded:: 1.0.0 N) r\r0r rDrZrOrAr[rrc)rrZrDrAr[ras rr zComparableProperty.__init__sqD  $''00222$"4E:<**<E  DI %%%%%rc.|||Srrrs rr>z&ComparableProperty._comparator_factory;rr)NNN)r&r'r(rOr r>rrs@rr0r0scFECGH&H&H&H&H&H&T5555555rr0N)rOrrr interfacesrrrrr r rr r rr langhelpersdependency_forrSrrdeprecated_clsr0rPrrr8s &&&&&&&&&&&&9H9H9H9H9H9H9H9Hx  !< NNRARARARARA*RARAONRAj   !< NN2525252525 22525ON25j  !< NN(OND  !< NN  N5N5N5N5N5+N5N5 ONN5N5N5r