SQLAlchemy JSONField
`sqlalchemy-jsonfield` provides a `JSONField` implementation for SQLAlchemy, allowing Python dictionaries to be stored in database JSON columns. It includes `JSONMutableDict` for automatic change tracking of mutable dictionary operations. The current stable version is 1.0.2, and it follows an infrequent, maintenance-focused release cadence.
Warnings
- gotcha Failing to use `JSONMutableDict` will prevent SQLAlchemy from detecting in-place modifications to the JSON data. If you define a `JSONField` as `sa.Column(JSONField(dict))` instead of `sa.Column(JSONField(JSONMutableDict))`, changes like `instance.json_data['key'] = 'value'` will not be saved unless the entire dictionary is reassigned (`instance.json_data = new_dict`).
- breaking Prior to version 0.7.0, `sqlalchemy-jsonfield` might have implicitly or explicitly relied on the `ujson` library for serialization. From version 0.7.0 onwards, it defaults to Python's standard `json` library and allows specifying a custom JSON library (e.g., `json=ujson`) via the `JSONField` constructor. This change could subtly alter serialization behavior or performance if your application implicitly depended on `ujson`'s characteristics.
Install
-
pip install sqlalchemy-jsonfield
Imports
- JSONField
from sqlalchemy_jsonfield import JSONField
- JSONMutableDict
from sqlalchemy_jsonfield import JSONMutableDict
Quickstart
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_jsonfield import JSONField, JSONMutableDict
# Define the base for declarative models
Base = declarative_base()
# Define a model with a JSONField
class Data(Base):
__tablename__ = 'data'
id = sa.Column(sa.Integer, primary_key=True)
# Use JSONField with JSONMutableDict to enable automatic change tracking
json_data = sa.Column(JSONField(JSONMutableDict), default={})
# Setup database engine and session
engine = sa.create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
try:
# Create a new item
item = Data(json_data={'initial_key': 'initial_value', 'list_data': [1, 2]})
session.add(item)
session.commit()
print(f"Created item ID: {item.id}, Data: {item.json_data}")
# Retrieve the item
retrieved_item = session.query(Data).filter_by(id=item.id).first()
print(f"Retrieved item ID: {retrieved_item.id}, Data: {retrieved_item.json_data}")
# Update the JSON data in-place (changes detected by JSONMutableDict)
retrieved_item.json_data['new_key'] = 'new_value'
retrieved_item.json_data['list_data'].append(3)
session.commit()
print(f"Updated item ID: {retrieved_item.id}, Data: {retrieved_item.json_data}")
# Verify update by re-retrieving
verified_item = session.query(Data).filter_by(id=item.id).first()
print(f"Verified item ID: {verified_item.id}, Data: {verified_item.json_data}")
finally:
session.close()