class JSON(Indexable, TypeEngine):
Known subclasses: sqlalchemy.dialects.mssql.json.JSON
, sqlalchemy.dialects.mysql.json.JSON
, sqlalchemy.dialects.postgresql.json.JSON
, sqlalchemy.dialects.sqlite.json.JSON
Represent a SQL JSON type.
Note
_types.JSON
is provided as a facade for vendor-specific
JSON types. Since it supports JSON SQL operations, it only
works on backends that have an actual JSON type, currently:
sqlalchemy.dialects.postgresql.JSON
and
sqlalchemy.dialects.postgresql.JSONB
for backend-specific
notessqlalchemy.dialects.mysql.JSON
for backend-specific notessqlalchemy.dialects.sqlite.JSON
for backend-specific notessqlalchemy.dialects.mssql.JSON
for backend-specific notes_types.JSON
is part of the Core in support of the growing
popularity of native JSON datatypes.
The _types.JSON
type stores arbitrary JSON format data, e.g.:
data_table = Table('data_table', metadata, Column('id', Integer, primary_key=True), Column('data', JSON) ) with engine.connect() as conn: conn.execute( data_table.insert(), data = {"key1": "value1", "key2": "value2"} )
JSON-Specific Expression Operators
The _types.JSON
datatype provides these additional SQL operations:
Keyed index operations:
data_table.c.data['some key']
Integer index operations:
data_table.c.data[3]
Path index operations:
data_table.c.data[('key_1', 'key_2', 5, ..., 'key_n')]
Data casters for specific JSON element types, subsequent to an index or path operation being invoked:
data_table.c.data["some key"].as_integer()
New in version 1.3.11.
Additional operations may be available from the dialect-specific versions
of _types.JSON
, such as
sqlalchemy.dialects.postgresql.JSON
and
sqlalchemy.dialects.postgresql.JSONB
which both offer additional
PostgreSQL-specific operations.
Casting JSON Elements to Other Types
Index operations, i.e. those invoked by calling upon the expression using
the Python bracket operator as in some_column['some key'], return an
expression object whose type defaults to _types.JSON
by default,
so that
further JSON-oriented instructions may be called upon the result type.
However, it is likely more common that an index operation is expected
to return a specific scalar element, such as a string or integer. In
order to provide access to these elements in a backend-agnostic way,
a series of data casters are provided:
.JSON.Comparator.as_string
- return the element as a string.JSON.Comparator.as_boolean
- return the element as a boolean.JSON.Comparator.as_float
- return the element as a float.JSON.Comparator.as_integer
- return the element as an integerThese data casters are implemented by supporting dialects in order to assure that comparisons to the above types will work as expected, such as:
# integer comparison data_table.c.data["some_integer_key"].as_integer() == 5 # boolean comparison data_table.c.data["some_boolean"].as_boolean() == True
Note
The data caster functions are new in version 1.3.11, and supersede the previous documented approaches of using CAST; for reference, this looked like:
from sqlalchemy import cast, type_coerce from sqlalchemy import String, JSON cast( data_table.c.data['some_key'], String ) == type_coerce(55, JSON)
The above case now works directly as:
data_table.c.data['some_key'].as_integer() == 5
For details on the previous comparison approach within the 1.3.x series, see the documentation for SQLAlchemy 1.2 or the included HTML files in the doc/ directory of the version's distribution.
Detecting Changes in JSON columns when using the ORM
The _types.JSON
type, when used with the SQLAlchemy ORM, does not
detect in-place mutations to the structure. In order to detect these, the
sqlalchemy.ext.mutable
extension must be used. This extension will
allow "in-place" changes to the datastructure to produce events which
will be detected by the unit of work. See the example at .HSTORE
for a simple example involving a dictionary.
Support for JSON null vs. SQL NULL
When working with NULL values, the _types.JSON
type recommends the
use of two specific constants in order to differentiate between a column
that evaluates to SQL NULL, e.g. no value, vs. the JSON-encoded string
of "null". To insert or select against a value that is SQL NULL,
use the constant .null
:
from sqlalchemy import null conn.execute(table.insert(), json_value=null())
To insert or select against a value that is JSON "null", use the
constant _types.JSON.NULL
:
conn.execute(table.insert(), json_value=JSON.NULL)
The _types.JSON
type supports a flag
:paramref:`_types.JSON.none_as_null` which when set to True will result
in the Python constant None evaluating to the value of SQL
NULL, and when set to False results in the Python constant
None evaluating to the value of JSON "null". The Python
value None may be used in conjunction with either
_types.JSON.NULL
and .null
in order to indicate NULL
values, but care must be taken as to the value of the
:paramref:`_types.JSON.none_as_null` in these cases.
Customizing the JSON Serializer
The JSON serializer and deserializer used by _types.JSON
defaults to
Python's json.dumps and json.loads functions; in the case of the
psycopg2 dialect, psycopg2 may be using its own custom loader function.
In order to affect the serializer / deserializer, they are currently
configurable at the _sa.create_engine
level via the
:paramref:`_sa.create_engine.json_serializer` and
:paramref:`_sa.create_engine.json_deserializer` parameters. For example,
to turn off ensure_ascii:
engine = create_engine( "sqlite://", json_serializer=lambda obj: json.dumps(obj, ensure_ascii=False))
See Also
sqlalchemy.dialects.postgresql.JSON
sqlalchemy.dialects.postgresql.JSONB
sqlalchemy.dialects.mysql.JSON
sqlalchemy.dialects.sqlite.JSON
Class | Comparator |
Define comparison operations for _types.JSON . |
Class | JSONElementType |
Common function for index / path elements in a JSON expression. |
Class | JSONIndexType |
Placeholder for the datatype of a JSON index value. |
Class | JSONIntIndexType |
Placeholder for the datatype of a JSON index value. |
Class | JSONPathType |
Placeholder type for JSON path operations. |
Class | JSONStrIndexType |
Placeholder for the datatype of a JSON index value. |
Method | __init__ |
Construct a _types.JSON type. |
Method | bind_processor |
Return a conversion function for processing bind values. |
Method | result_processor |
Return a conversion function for processing result row values. |
Constant | NULL |
Describe the json value of NULL. |
Method | should_evaluate_none.setter |
Undocumented |
Class Variable | __visit_name__ |
Undocumented |
Class Variable | hashable |
Flag, if False, means values from this type aren't hashable. |
Instance Variable | none_as_null |
Undocumented |
Property | _str_impl |
Undocumented |
Property | python_type |
Return the Python type object expected to be returned by instances of this type, if known. |
Property | should_evaluate_none |
Alias of _types.JSON.none_as_null |
Inherited from TypeEngine
:
Method | adapt |
Produce an "adapted" form of this type, given an "impl" class to work with. |
Method | as_generic |
Return an instance of the generic type corresponding to this type using heuristic rule. The method may be overridden if this heuristic rule is not sufficient. |
Method | bind_expression |
Given a bind value (i.e. a .BindParameter instance), return a SQL expression in its place. |
Method | coerce_compared_value |
Suggest a type for a 'coerced' Python value in an expression. |
Method | column_expression |
Given a SELECT column expression, return a wrapping SQL expression. |
Method | compare_against_backend |
Compare this type against the given backend type. |
Method | compare_values |
Compare two values for equality. |
Method | compile |
Produce a string-compiled form of this .TypeEngine . |
Method | dialect_impl |
Return a dialect-specific implementation for this .TypeEngine . |
Method | evaluates_none |
Return a copy of this type which has the .should_evaluate_none flag set to True. |
Method | get_dbapi_type |
Return the corresponding type object from the underlying DB-API, if any. |
Method | literal_processor |
Return a conversion function for processing literal values that are to be rendered directly without using binds. |
Method | with_variant |
Produce a new type object that will utilize the given type when applied to the dialect of the given name. |
Class Variable | sort_key_function |
A sorting function that can be passed as the key to sorted. |
Static Method | _to_instance |
Undocumented |
Method | __repr__ |
Undocumented |
Method | __str__ |
Undocumented |
Method | _cached_bind_processor |
Return a dialect-specific bind processor for this type. |
Method | _cached_custom_processor |
Undocumented |
Method | _cached_literal_processor |
Return a dialect-specific literal processor for this type. |
Method | _cached_result_processor |
Return a dialect-specific result processor for this type. |
Method | _compare_type_affinity |
Undocumented |
Method | _default_dialect |
Undocumented |
Method | _dialect_info |
Return a dialect-specific registry which caches a dialect-specific implementation, bind processing function, and one or more result processing functions. |
Method | _gen_dialect_impl |
Undocumented |
Method | _resolve_for_literal |
adjust this type given a literal Python value that will be stored in a bound parameter. |
Method | _unwrapped_dialect_impl |
Return the 'unwrapped' dialect impl for this type. |
Method | copy |
Undocumented |
Method | copy_value |
Undocumented |
Class Variable | _is_array |
Undocumented |
Class Variable | _is_table_value |
Undocumented |
Class Variable | _is_tuple_type |
Undocumented |
Class Variable | _is_type_decorator |
Undocumented |
Class Variable | _isnull |
Undocumented |
Class Variable | _sqla_type |
Undocumented |
Property | _generic_type_affinity |
Undocumented |
Property | _has_bind_expression |
memoized boolean, check if bind_expression is implemented. |
Property | _has_column_expression |
memoized boolean, check if column_expression is implemented. |
Property | _static_cache_key |
Undocumented |
Property | _type_affinity |
Return a rudimental 'affinity' value expressing the general class of type. |
Inherited from Traversible
(via TypeEngine
):
Method | get_children |
Return immediate child .visitors.Traversible elements of this .visitors.Traversible . |
Method | __class_getitem__ |
Undocumented |
sqlalchemy.dialects.postgresql.json.JSON
_types.JSON
type.Parameters | |
none_as_null | Undocumented |
none_as_null=False | 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 from sqlalchemy import null conn.execute(table.insert(), data=null()) Note :paramref:`_types.JSON.none_as_null` does not apply to the values passed to :paramref:`_schema.Column.default` and :paramref:`_schema.Column.server_default`; a value of None passed for these parameters means "no default present". Additionally, when used in SQL comparison expressions, the
Python value None continues to refer to SQL null, and not
JSON NULL. The :paramref:`_types.JSON.none_as_null` flag refers
explicitly to the persistence of the value within an
INSERT or UPDATE statement. The See Also
|
sqlalchemy.dialects.postgresql.pygresql._PGJSON
, sqlalchemy.dialects.postgresql.pygresql._PGJSONB
Return a conversion function for processing bind values.
Returns a callable which will receive a bind parameter value as the sole positional argument and will return a value to send to the DB-API.
If processing is not necessary, the method should return None.
Note
This method is only called relative to a dialect specific type
object, which is often private to a dialect in use and is not
the same type object as the public facing one, which means it's not
feasible to subclass a .types.TypeEngine
class in order to
provide an alternate _types.TypeEngine.bind_processor
method, unless subclassing the _types.UserDefinedType
class explicitly.
To provide alternate behavior for
_types.TypeEngine.bind_processor
, implement a
_types.TypeDecorator
class and provide an implementation
of _types.TypeDecorator.process_bind_param
.
See Also
Parameters | |
dialect | Dialect instance in use. |
sqlalchemy.databases.sqlite._SQliteJson
, sqlalchemy.dialects.postgresql.asyncpg.AsyncpgJSON
, sqlalchemy.dialects.postgresql.asyncpg.AsyncpgJSONB
, sqlalchemy.dialects.postgresql.pg8000._PGJSON
, sqlalchemy.dialects.postgresql.pg8000._PGJSONB
, sqlalchemy.dialects.postgresql.psycopg2._PGJSON
, sqlalchemy.dialects.postgresql.psycopg2._PGJSONB
, sqlalchemy.dialects.postgresql.pygresql._PGJSON
, sqlalchemy.dialects.postgresql.pygresql._PGJSONB
Return a conversion function for processing result row values.
Returns a callable which will receive a result row column value as the sole positional argument and will return a value to return to the user.
If processing is not necessary, the method should return None.
Note
This method is only called relative to a dialect specific type
object, which is often private to a dialect in use and is not
the same type object as the public facing one, which means it's not
feasible to subclass a .types.TypeEngine
class in order to
provide an alternate _types.TypeEngine.result_processor
method, unless subclassing the _types.UserDefinedType
class explicitly.
To provide alternate behavior for
_types.TypeEngine.result_processor
, implement a
_types.TypeDecorator
class and provide an implementation
of _types.TypeDecorator.process_result_value
.
See Also
Parameters | |
dialect | Dialect instance in use. |
coltype | DBAPI coltype argument received in cursor.description. |
Describe the json value of NULL.
This value is used to force the JSON value of "null" to be
used as the value. A value of Python None will be recognized
either as SQL NULL or JSON "null", based on the setting
of the :paramref:`_types.JSON.none_as_null` flag; the
_types.JSON.NULL
constant can be used to always resolve to JSON "null" regardless
of this setting. This is in contrast to the _expression.null
construct,
which always resolves to SQL NULL. E.g.:
from sqlalchemy import null from sqlalchemy.dialects.postgresql import JSON # will *always* insert SQL NULL obj1 = MyObject(json_value=null()) # will *always* insert JSON string "null" obj2 = MyObject(json_value=JSON.NULL) session.add_all([obj1, obj2]) session.commit()
In order to set JSON NULL as a default value for a column, the most
transparent method is to use _expression.text
:
Table( 'my_table', metadata, Column('json_data', JSON, default=text("'null'")) )
While it is possible to use _types.JSON.NULL
in this context, the
_types.JSON.NULL
value will be returned as the value of the
column,
which in the context of the ORM or other repurposing of the default
value, may not be desirable. Using a SQL expression means the value
will be re-fetched from the database within the context of retrieving
generated defaults.
Value |
|
bool
=
sqlalchemy.types.TypeEngine.hashable
Flag, if False, means values from this type aren't hashable.
Used by the ORM when uniquing result lists.
sqlalchemy.types.TypeEngine.python_type
Return the Python type object expected to be returned by instances of this type, if known.
Basically, for those types which enforce a return type, or are known across the board to do such for all common DBAPIs (like int for example), will return that type.
If a return type is not defined, raises NotImplementedError.
Note that any type also accommodates NULL in SQL which means you can also get back None from any type in practice.