websauna.system.model.json module¶
Mutable JSON data support for SQLAlchemy.
Based on the original Kotti CMS implementation:
-
class
websauna.system.model.json.
MutationDict
(data)[source]¶ Bases:
websauna.system.model.json.WebsaunaFriendlyMutable
http://www.sqlalchemy.org/docs/orm/extensions/mutable.html
-
clear
(*args, **kwargs)¶
-
classmethod
coerce
(key, value)[source]¶ Given a value, coerce it into the target type.
Can be overridden by custom subclasses to coerce incoming data into a particular type.
By default, raises
ValueError
.This method is called in different scenarios depending on if the parent class is of type
Mutable
or of typeMutableComposite
. In the case of the former, it is called for both attribute-set operations as well as during ORM loading operations. For the latter, it is only called during attribute-set operations; the mechanics of thecomposite()
construct handle coercion during load operations.- Parameters
key – string name of the ORM-mapped attribute being set.
value – the incoming value.
- Returns
the method should return the coerced value, or raise
ValueError
if the coercion cannot be completed.
-
get
(*args, **kwargs)¶
-
items
(*args, **kwargs)¶
-
keys
(*args, **kwargs)¶
-
pop
(*args, **kwargs)¶
-
setdefault
(*args, **kwargs)¶
-
update
(*args, **kwargs)¶
-
values
(*args, **kwargs)¶
-
-
class
websauna.system.model.json.
MutationList
(data)[source]¶ Bases:
websauna.system.model.json.WebsaunaFriendlyMutable
-
append
(*args, **kwargs)¶
-
clear
(*args, **kwargs)¶
-
classmethod
coerce
(key, value)[source]¶ Given a value, coerce it into the target type.
Can be overridden by custom subclasses to coerce incoming data into a particular type.
By default, raises
ValueError
.This method is called in different scenarios depending on if the parent class is of type
Mutable
or of typeMutableComposite
. In the case of the former, it is called for both attribute-set operations as well as during ORM loading operations. For the latter, it is only called during attribute-set operations; the mechanics of thecomposite()
construct handle coercion during load operations.- Parameters
key – string name of the ORM-mapped attribute being set.
value – the incoming value.
- Returns
the method should return the coerced value, or raise
ValueError
if the coercion cannot be completed.
-
extend
(*args, **kwargs)¶
-
insert
(*args, **kwargs)¶
-
pop
(*args, **kwargs)¶
-
remove
(*args, **kwargs)¶
-
-
class
websauna.system.model.json.
NestedMixin
(*args, **kwargs)[source]¶ Bases:
object
Base class to to nested dict and list state tracking.
-
class
websauna.system.model.json.
NestedMutationDict
(*args, **kwargs)[source]¶ Bases:
websauna.system.model.json.NestedMixin
,websauna.system.model.json.MutationDict
-
class
websauna.system.model.json.
NestedMutationList
(*args, **kwargs)[source]¶ Bases:
websauna.system.model.json.NestedMixin
,websauna.system.model.json.MutationList
-
class
websauna.system.model.json.
WebsaunaFriendlyMutable
[source]¶ Bases:
sqlalchemy.ext.mutable.Mutable
A patched mutable that can deal with our generic column types.
-
classmethod
as_mutable
(orig_sqltype)[source]¶ Mark the value as nested mutable value.
What happens here
We coerce the return value - the type value set on sqlalchemy.Column() to the underlying SQL typ
We mark this type value with a marker attribute
Then we set a global SQAlchemy mapper event handler
When mapper is done setting up our model classes, it will call the event handler for all models
We check if any of the models columns have our marked type value as the value
If so we call
associate_with_attribute
for this model and column that sets upMutableBase._listen_on_attribute
event handlers. These event handlers take care of taking the raw dict coming out from database and wrapping it to NestedMutableDict.
- Parameters
orig_sqltype – Usually websauna.system.model.column.JSONB instance
- Returns
Marked and coerced type value
-
classmethod
-
websauna.system.model.json.
init_for_json
(cls)[source]¶ Check if we need to add JSON column specific SQLAlchemy event listers for this model.
-
websauna.system.model.json.
json_serializer
(d)[source]¶ MutationDict friendly json_serializer for create_engine().
-
websauna.system.model.json.
setup_default_value_handling
(cls)[source]¶ A SQLAlchemy model class decorator that ensures JSON/JSONB default values are correctly handled.
Settings default values for JSON fields have a bunch of issues, because dict and list instances need to be wrapped in
NestedMutationDict
andNestedMutationList
that correclty set the parent object dirty state if the container content is modified. This class decorator sets up hooks, so that default values are automatically converted to their wrapped versions.Note
We are only concerned about initial values. When values are loaded from the database,
Mutable
base class ofNestedMutationDict
correctly sets up the parent pointers.Note
This must be applid to the class directly, as SQLAlchemy does not seem ot pick it up if it’s applied to an (abstract) parent class.
This might be addressed in future SQLAlchemy / Websauna versions so that we can get rid of this ugly little decorator.
-
websauna.system.model.json.
wrap_as_nested
(key, data, parent)[source]¶ Convert raw dict or list data to a NestedMutable version with a parent pointer set.
After this is in-place, the object dirty state should be automatically tracked.
-
websauna.system.model.json.
wrapper_class
¶