Base
ModelWithSchemaType = TypeVar('ModelWithSchemaType', bound='ModelWithSchema')
module-attribute
logger = logging.getLogger(__name__)
module-attribute
CrudMixin
deleted = mapped_column(default=False)
class-attribute
instance-attribute
version
instance-attribute
crud_from_schema_kwargs(schema)
classmethod
crud_to_schema_kwargs()
Model
Bases: AsyncAttrs, DeclarativeBase
All models should inherit from this Model base (or a subclass of it).
__abstract__ = True
class-attribute
instance-attribute
ModelWithSchema
Bases: Model
Any model that has a schema equivalent should subclass from this.
Models should only be used when loading from db or saving to db. For all other purposes, the schema equivalent should be used. The schemas have better validation and are easier to work with because it is more obvious what is and isn't loaded (for models, if a relationship is not loaded, trying to access it will raise an error because it will be outside the db session).
__abstract__ = True
class-attribute
instance-attribute
fully_load_model_options()
classmethod
The options required to fully load the model (i.e. joined/selectinload for all relationships with 'raise'.
The additional options required to fully load the model.
E.g. fully_loaded_model = await db.get(Model, id, options=Model.fully_load_model_options())
Examples:
return [sqla.orm.selectinload(Model.relationship)]
id()
model_from_schema(schema)
abstractmethod
classmethod
Create a new instance of the model from the schema equivalent (i.e. When model not already in db (id=None)).
Note: Be careful not to create new models for data that exists in the db already. In those cases, require the existing models to be provided as arguments to this method. (PyCharm will complain about the signature, unless additional values have defaults, but might make sense to just ignore the warnings if the additional arguments really are required)
Note: For further optimization, if there are many associated models, and they don't otherwise need to be loaded, then initialize without them, and then do a separate sqla.update to directly add the id of this model as a foreign key to the associated models.
to_schema()
abstractmethod
Convert to the schema equivalent.
Note: Model and sub-models must be fully loaded in order to convert to schema. This ensures that the conversion is efficient and does not make many sequential database calls.
Example of loading sub-models initially:
full_model = await db.scalar(select(FullRequestModel).options(
joinedload(FullRequestModel.request_messages)
)
Anything not already should be filled with None or some other default value.
VersionedMixin
Adds methods and values for storing in database (including id, version, deleted).