U a*@sddlmZddlmZddlmZddlmZdZej ej Z ej de ddd Z ej d e ddd Zej d e ddd Zej d e ddd Zej d e ddd Zej de ddd Zej de ddd ZGdddejjZGdddejZGdddeZdS))absolute_import)types)util) operators)JSONJSONBz->>T) precedenceZnatural_self_precedentZeager_groupingz#>>?z?&z?|z@>z<@c@seZdZddZddZdS) JSONPathTypecs||fdd}|S)Ncs>t|tjjstdd|D}dd|}r:|}|S)NcSsg|]}t|qSr text_type.0elemr r dC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\dialects\postgresql\json.py Ksz@JSONPathType.bind_processor..process..{%s},  isinstancercollections_abcSequenceAssertionErrorjoinvaluetokensZ super_procr rprocessIs z,JSONPathType.bind_processor..process)Zstring_bind_processorselfdialectr r rrbind_processorFs  zJSONPathType.bind_processorcs||fdd}|S)Ncs>t|tjjstdd|D}dd|}r:|}|S)NcSsg|]}t|qSr r rr r rrXszCJSONPathType.literal_processor..process..rrrrrr rr Vs z/JSONPathType.literal_processor..process)Zstring_literal_processorr!r rrliteral_processorSs  zJSONPathType.literal_processorN)__name__ __module__ __qualname__r$r%r r r rr Es r csBeZdZdZeZdfdd ZGdddejj Z e Z Z S) ra Represent the PostgreSQL JSON type. :class:`_postgresql.JSON` is used automatically whenever the base :class:`_types.JSON` datatype is used against a PostgreSQL backend, however base :class:`_types.JSON` datatype does not provide Python accessors for PostgreSQL-specific comparison methods such as :meth:`_postgresql.JSON.Comparator.astext`; additionally, to use PostgreSQL ``JSONB``, the :class:`_postgresql.JSONB` datatype should be used explicitly. .. seealso:: :class:`_types.JSON` - main documentation for the generic cross-platform JSON datatype. The operators provided by the PostgreSQL version of :class:`_types.JSON` include: * Index operations (the ``->`` operator):: data_table.c.data['some key'] data_table.c.data[5] * Index operations returning text (the ``->>`` operator):: data_table.c.data['some key'].astext == 'some value' Note that equivalent functionality is available via the :attr:`.JSON.Comparator.as_string` accessor. * Index operations with CAST (equivalent to ``CAST(col ->> ['some key'] AS )``):: data_table.c.data['some key'].astext.cast(Integer) == 5 Note that equivalent functionality is available via the :attr:`.JSON.Comparator.as_integer` and similar accessors. * Path index operations (the ``#>`` operator):: data_table.c.data[('key_1', 'key_2', 5, ..., 'key_n')] * Path index operations returning text (the ``#>>`` operator):: data_table.c.data[('key_1', 'key_2', 5, ..., 'key_n')].astext == 'some value' .. versionchanged:: 1.1 The :meth:`_expression.ColumnElement.cast` operator on JSON objects now requires that the :attr:`.JSON.Comparator.astext` modifier be called explicitly, if the cast works only from a textual string. Index operations return an expression object whose type defaults to :class:`_types.JSON` by default, so that further JSON-oriented instructions may be called upon the result type. Custom serializers and deserializers are specified at the dialect level, that is using :func:`_sa.create_engine`. The reason for this is that when using psycopg2, the DBAPI only allows serializers at the per-cursor or per-connection level. E.g.:: engine = create_engine("postgresql://scott:tiger@localhost/test", json_serializer=my_serialize_fn, json_deserializer=my_deserialize_fn ) When using the psycopg2 dialect, the json_deserializer is registered against the database using ``psycopg2.extras.register_default_json``. .. seealso:: :class:`_types.JSON` - Core level JSON type :class:`_postgresql.JSONB` .. versionchanged:: 1.1 :class:`_postgresql.JSON` is now a PostgreSQL- specific specialization of the new :class:`_types.JSON` type. FNcs$tt|j|d|dk r ||_dS)a+Construct a :class:`_types.JSON` type. :param none_as_null: if True, persist the value ``None`` as a SQL NULL value, not the JSON encoding of ``null``. Note that when this flag is False, the :func:`.null` construct can still be used to persist a NULL value:: from sqlalchemy import null conn.execute(table.insert(), data=null()) .. versionchanged:: 0.9.8 - Added ``none_as_null``, and :func:`.null` is now supported in order to persist a NULL value. .. seealso:: :attr:`_types.JSON.NULL` :param astext_type: the type to use for the :attr:`.JSON.Comparator.astext` accessor on indexed attributes. Defaults to :class:`_types.Text`. .. versionadded:: 1.1 ) none_as_nullN)superr__init__ astext_type)r"r)r, __class__r rr+sz JSON.__init__c@seZdZdZeddZdS)zJSON.Comparator6Define comparison operations for :class:`_types.JSON`.cCsPt|jjjtjjr0|jjjt |jj|jj dS|jjjt |jj|jj dSdS)aOn an indexed expression, use the "astext" (e.g. "->>") conversion when rendered in SQL. E.g.:: select(data_table.c.data['some key'].astext) .. seealso:: :meth:`_expression.ColumnElement.cast` Z result_typeN) rexprrighttypesqltypesrr leftoperateJSONPATH_ASTEXTr,ASTEXT)r"r r rastextszJSON.Comparator.astextN)r&r'r(__doc__propertyr9r r r r Comparatorsr<)FN) r&r'r(r:r4Textr,r+rr<comparator_factory __classcell__r r r-rras Src@s*eZdZdZdZGdddejZeZdS)raRepresent the PostgreSQL JSONB type. The :class:`_postgresql.JSONB` type stores arbitrary JSONB format data, e.g.:: data_table = Table('data_table', metadata, Column('id', Integer, primary_key=True), Column('data', JSONB) ) with engine.connect() as conn: conn.execute( data_table.insert(), data = {"key1": "value1", "key2": "value2"} ) The :class:`_postgresql.JSONB` type includes all operations provided by :class:`_types.JSON`, including the same behaviors for indexing operations. It also adds additional operators specific to JSONB, including :meth:`.JSONB.Comparator.has_key`, :meth:`.JSONB.Comparator.has_all`, :meth:`.JSONB.Comparator.has_any`, :meth:`.JSONB.Comparator.contains`, and :meth:`.JSONB.Comparator.contained_by`. Like the :class:`_types.JSON` type, the :class:`_postgresql.JSONB` type does not detect in-place changes when used with the ORM, unless the :mod:`sqlalchemy.ext.mutable` extension is used. Custom serializers and deserializers are shared with the :class:`_types.JSON` class, using the ``json_serializer`` and ``json_deserializer`` keyword arguments. These must be specified at the dialect level using :func:`_sa.create_engine`. When using psycopg2, the serializers are associated with the jsonb type using ``psycopg2.extras.register_default_jsonb`` on a per-connection basis, in the same way that ``psycopg2.extras.register_default_json`` is used to register these handlers with the json type. .. versionadded:: 0.9.7 .. seealso:: :class:`_types.JSON` c@s8eZdZdZddZddZddZdd Zd d Zd S) zJSONB.Comparatorr/cCs|jt|tjdS)zvBoolean expression. Test for presence of a key. Note that the key may be a SQLA expression. r0)r6HAS_KEYr4Booleanr"otherr r rhas_key(szJSONB.Comparator.has_keycCs|jt|tjdS)z;Boolean expression. Test for presence of all keys in jsonbr0)r6HAS_ALLr4rArBr r rhas_all.szJSONB.Comparator.has_allcCs|jt|tjdS)z:Boolean expression. Test for presence of any key in jsonbr0)r6HAS_ANYr4rArBr r rhas_any2szJSONB.Comparator.has_anycKs|jt|tjdS)zBoolean expression. Test if keys (or array) are a superset of/contained the keys of the argument jsonb expression. r0)r6CONTAINSr4rA)r"rCkwargsr r rcontains6szJSONB.Comparator.containscCs|jt|tjdS)z|Boolean expression. Test if keys are a proper subset of the keys of the argument jsonb expression. r0)r6 CONTAINED_BYr4rArBr r r contained_by<s zJSONB.Comparator.contained_byN) r&r'r(r:rDrFrHrKrMr r r rr<%s r<N)r&r'r(r:Z__visit_name__rr<r>r r r rrs/rN) __future__rrr4rZsqlr__all__Z _PRECEDENCEZjson_getitem_opZidx_precedenceZ custom_opr8r7r@rErGrIrLrr rr r r rsf