class documentation

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

View In Hierarchy

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:

  • PostgreSQL - see sqlalchemy.dialects.postgresql.JSON and sqlalchemy.dialects.postgresql.JSONB for backend-specific notes
  • MySQL - see sqlalchemy.dialects.mysql.JSON for backend-specific notes
  • SQLite as of version 3.9 - see sqlalchemy.dialects.sqlite.JSON for backend-specific notes
  • Microsoft SQL Server 2016 and later - see sqlalchemy.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 integer

These 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
New in version 1.3.11: Added type-specific casters for the basic JSON data element types.

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))
Changed in version 1.3.7: SQLite dialect's json_serializer and json_deserializer parameters renamed from _json_serializer and _json_deserializer.

See Also

sqlalchemy.dialects.postgresql.JSON

sqlalchemy.dialects.postgresql.JSONB

sqlalchemy.dialects.mysql.JSON

sqlalchemy.dialects.sqlite.JSON

New in version 1.1.
Class ​Comparator Define comparison operations for _types.JSON.
Class ​JSONElement​Type Common function for index / path elements in a JSON expression.
Class ​JSONIndex​Type Placeholder for the datatype of a JSON index value.
Class ​JSONInt​Index​Type Placeholder for the datatype of a JSON index value.
Class ​JSONPath​Type Placeholder type for JSON path operations.
Class ​JSONStr​Index​Type 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
def __init__(self, none_as_null=False):
Construct a _types.JSON type.
Parameters
none​_as​_nullUndocumented
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 .null construct can still be used to persist a NULL value:

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 _types.JSON.NULL value should be used for SQL expressions that wish to compare to JSON null.

See Also

.types.JSON.NULL

def bind_processor(self, dialect):

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.

Parameters
dialectDialect instance in use.
def result_processor(self, dialect, coltype):

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.

Parameters
dialectDialect instance in use.
coltypeDBAPI coltype argument received in cursor.description.
NULL =

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
util.symbol('JSON_NULL')
@should_evaluate_none.setter
def should_evaluate_none(self, value):

Undocumented

__visit_name__: str =

Undocumented

hashable: bool =

Flag, if False, means values from this type aren't hashable.

Used by the ORM when uniquing result lists.

none_as_null =

Undocumented

@util.memoized_property
_str_impl =

Undocumented

@property
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.

@property
should_evaluate_none =
Alias of _types.JSON.none_as_null