L i.ddlZddlmZddlmZddlmZddlmZddlmZddlmZdd lm Z d d l m Z d d l mZd ZGdde j"e j$e j&ZGddej*ZGddej*ZGddej*ZGddej*ZGddej*ZGddej*ZGddej*ZGddej*Zej<d ej>Z ej<d!ej>Z!d"Z"d#Z#d$Z$y)%N)ARRAY) CONTAINED_BY)CONTAINS)GETITEM)HAS_ALL)HAS_ANY)HAS_KEY)types) functions)HSTOREhstoreceZdZdZdZdZejZd dZ GddejjejjZ e Z dZdZy) ra/ Represent the PostgreSQL HSTORE type. The :class:`.HSTORE` type stores dictionaries containing strings, e.g.:: data_table = Table( "data_table", metadata, Column("id", Integer, primary_key=True), Column("data", HSTORE), ) with engine.connect() as conn: conn.execute( data_table.insert(), data={"key1": "value1", "key2": "value2"} ) :class:`.HSTORE` provides for a wide range of operations, including: * Index operations:: data_table.c.data["some key"] == "some value" * Containment operations:: data_table.c.data.has_key("some key") data_table.c.data.has_all(["one", "two", "three"]) * Concatenation:: data_table.c.data + {"k1": "v1"} For a full list of special methods see :class:`.HSTORE.comparator_factory`. .. container:: topic **Detecting Changes in HSTORE columns when using the ORM** For usage with the SQLAlchemy ORM, it may be desirable to combine the usage of :class:`.HSTORE` with :class:`.MutableDict` dictionary now part of the :mod:`sqlalchemy.ext.mutable` extension. This extension will allow "in-place" changes to the dictionary, e.g. addition of new keys or replacement/removal of existing keys to/from the current dictionary, to produce events which will be detected by the unit of work:: from sqlalchemy.ext.mutable import MutableDict class MyClass(Base): __tablename__ = "data_table" id = Column(Integer, primary_key=True) data = Column(MutableDict.as_mutable(HSTORE)) my_object = session.query(MyClass).one() # in-place mutation, requires Mutable extension # in order for the ORM to detect my_object.data["some_key"] = "some value" session.commit() When the :mod:`sqlalchemy.ext.mutable` extension is not used, the ORM will not be alerted to any changes to the contents of an existing dictionary, unless that dictionary value is re-assigned to the HSTORE-attribute itself, thus generating a change event. .. seealso:: :class:`.hstore` - render the PostgreSQL ``hstore()`` function. FNc|||_yy)zConstruct a new :class:`.HSTORE`. :param text_type: the type that should be used for indexed values. Defaults to :class:`_types.Text`. N) text_type)selfrs k/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sqlalchemy/dialects/postgresql/hstore.py__init__zHSTORE.__init__ls  &DN !c^eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZy)HSTORE.Comparatorz2Define comparison operations for :class:`.HSTORE`.cN|jt|tjS)zvBoolean expression. Test for presence of a key. Note that the key may be a SQLA expression.  result_type)operater sqltypesBooleanrothers rhas_keyzHSTORE.Comparator.has_key{s<<H.processs%&(// rrR)rdialectrXs rbind_processorzHSTORE.bind_processor  rc d}|S)Nc | t|S|Sr-) _parse_hstorerVs rrXz(HSTORE.result_processor..processs $U++ rrR)rrYcoltyperXs rresult_processorzHSTORE.result_processorr[rr-)rNrOrPrQ__visit_name__hashablerTextrr IndexablerS Concatenablecomparator_factoryrZr`rRrrrrscKZNH I'K4%%x'<'<'G'GK4Z$  rrceZdZdZeZdZdZy)raHConstruct an hstore value within a SQL expression using the PostgreSQL ``hstore()`` function. The :class:`.hstore` function accepts one or two arguments as described in the PostgreSQL documentation. E.g.:: from sqlalchemy.dialects.postgresql import array, hstore select(hstore("key1", "value1")) select( hstore( array(["key1", "key2", "key3"]), array(["value1", "value2", "value3"]), ) ) .. seealso:: :class:`.HSTORE` - the PostgreSQL ``HSTORE`` datatype. TN)rNrOrPrQrr.name inherit_cacherRrrrrs2 D DMrrc,eZdZejZdZdZy)r2r6TN)rNrOrPrrr.rhrirRrrr2r2s   D DMrr2ceZdZeZdZdZy)r;r<TNrNrOrPrr.rhrirRrrr;r;s D DMrr;ceZdZeZdZdZy)r>r@TNrlrRrrr>r> s D DMrr>c8eZdZeej ZdZdZy)rBakeysTN rNrOrPrrrcr.rhrirRrrrBrB  D DMrrBc8eZdZeej ZdZdZy)rGavalsTNrprRrrrGrGrqrrGc8eZdZeej ZdZdZy)rJhstore_to_arrayTNrprRrrrJrJs  D DMrrJc8eZdZeej ZdZdZy)rLhstore_to_matrixTNrprRrrrLrL!s  D DMrrLz ( "(?P (\\ . | [^"])* )" # Quoted key ) [ ]* => [ ]* # Pair operator, optional adjoining whitespace ( (?P NULL ) # NULL value | "(?P (\\ . | [^"])* )" # Quoted value ) z [ ]* , [ ]* cd}t|}|t||z dz dt||}|t||t||zdz|}t||kDrd|ddz}t||kDr|dddz}d|||fzS)zformat an unmarshalling error.rrz[...]Nz5After %r, could not parse residual at position %d: %r)lenmaxmin) hstore_strposctxhslen parsed_tailresiduals r _parse_errorrEs C  OESsQ2Se_EK#c5/Cc A u,EFH ;# AB/  8}sCR=7* B F rc.i}d}tj|}||jdjddjdd}|jdrd}n1|jd jddjdd}|||<||j z }t j||d}|||j z }tj||d}||t |k7rtt|||S) aParse an hstore from its literal string representation. Attempts to approximate PG's hstore input parsing rules as closely as possible. Although currently this is not strictly necessary, since the current implementation of hstore's output syntax is stricter than what it accepts as input, the documentation makes no guarantees that will always be the case. rNr5\""\\\ value_nullrW) HSTORE_PAIR_REmatchgroupreplaceendHSTORE_DELIMITER_REr{ ValueErrorr)r~resultr pair_matchr5rW delim_matchs rr^r^ZsF C%%j1J  u%--eS9AA&$O   L )E  )$&  s  z~~)// 340@A  " ;??$ $C#))*ST*:; %  ( c*oj#677 MrcZddjfd|jDS)zxSerialize a dictionary into an hstore literal. Keys and values must both be strings (except None for values). c|dk(r|yt|tr%d|jddjddzSt|d|d ) NrWNULLz"%s"rrrrz in z position is not a string.)r8strrr)spositions rescz_serialize_hstore..escsS w 19 3 AIIdF3;;CGG G898D rz, c3NK|]\}}|dd|dyw)r5z=>rWNrR).0kvrs r z$_serialize_hstore..s+8<1C5M3q'?3s"%)joinitems)valrs @rr:r:s.  99@C  r)%rer?r operatorsrrrrr r r rsqlr sqlfunc__all__rdre TypeEnginerGenericFunctionrr2r;r>rBrGrJrLcompileVERBOSErrrr^r:rRrrrs2 #!' AX  !6!68K8KAHW $ $>W44 G33 722 '11 '11 722 G33 JJ !bjjJJ *'Tr