SQL ORM mixins and collections#
Module: restalchemy.storage.sql.orm
This module provides ORM-like behavior for DM models:
ObjectCollection— collection API exposed asModel.objects.SQLStorableMixin— mixin that addssave(),update(),delete()and integration with SQL tables.SQLStorableWithJSONFieldsMixin— specialization for models with JSON fields.
ObjectCollection#
ObjectCollection implements the collection interface for SQL-backed models.
Key methods:
get_all(filters=None, session=None, cache=False, limit=None, order_by=None, locked=False)- Returns a list of model instances.
- Uses
filters(DM filter structures) to build WHERE clauses. - Can use per-session query cache when
cache=True. get_one(filters=None, session=None, cache=False, locked=False)- Returns exactly one model instance.
- Raises
RecordNotFoundif no rows,HasManyRecordsif more than one. get_one_or_none(filters=None, session=None, cache=False, locked=False)- Returns a single instance or
Noneif not found. query(where_conditions, where_values, session=None, cache=False, limit=None, order_by=None, locked=False)- Executes a custom WHERE clause.
count(session=None, filters=None)- Returns the number of rows matching filters.
ObjectCollection uses:
- The SQL dialect via
engine.dialect. - The model's
restore_from_storage()method to convert rows into DM models.
Loading relationships#
A relationship the query did not prefetch arrives as an identifier, and the
model it names is read separately. get_all() and query() gather the
identifiers of the whole page and read them one query per relationship, rather
than one query per row, and do the same for what those objects point at in
turn.
- Rows of the page naming the same object are handed the same instance.
- An identifier the page does not find is left as it arrived, so a row pointing at a missing record fails exactly as it did before.
- A relationship declared with
prefetch=Trueis read by the query that reads the page (aLEFT JOIN) and does not take part in this. SQLStorableMixin.RELATIONSHIP_BATCH_SIZE(1000 by default) caps how many identifiers a single query asks for.
SQLStorableMixin#
SQLStorableMixin is intended to be combined with DM models to make them storable in SQL.
Requirements#
- The DM model must have a valid
__tablename__string. - There must be at least one ID property (
id_property=True).
Core responsibilities#
get_table()- Returns a
SQLTableinstance for the model, cached in__operational_storage__. insert(session=None)- Inserts the model into the table using current property values.
- Wraps dialect-specific exceptions into storage exceptions (e.g. conflicts).
save(session=None)- If the instance is not yet saved, calls
insert(). - Otherwise calls
update(). update(session=None, force=False)- Updates the row when the model is dirty or
force=True. - Validates the model before updating.
- Ensures exactly one row is updated (otherwise raises).
delete(session=None)- Deletes the row corresponding to the model's ID properties.
restore_from_storage(**kwargs)(class method)- Converts database row values (simple types) to DM property values.
- Constructs a model instance marked as saved.
Object collection binding#
SQLStorableMixin defines _ObjectCollection = ObjectCollection. In combination with base storage classes this provides:
Model.objects— a collection that usesObjectCollectionto perform queries.
Type conversion helpers#
to_simple_type(value)(class method)- Converts model instances or raw ID values to a form suitable for filters.
from_simple_type(value)(class method)- Converts raw ID values or prefetch results into model instances.
These helpers allow storage and API layers to work with IDs and prefetch structures transparently.
SQLStorableWithJSONFieldsMixin#
SQLStorableWithJSONFieldsMixin extends SQLStorableMixin for databases that do not support JSON fields natively.
Usage pattern:
- Inherit from
SQLStorableWithJSONFieldsMixininstead ofSQLStorableMixin. - Define
__jsonfields__as an iterable of field names that store JSON data.
Behavior:
restore_from_storage()- For fields listed in
__jsonfields__:- If the stored value is a string, parses it as JSON.
_get_prepared_data(properties=None)- For fields in
__jsonfields__, dumps Python data structures to compact JSON strings.
This allows you to keep JSON fields in your DM models while persisting them as text in databases that lack native JSON support.