mafw.db.db_model

The module provides functionality to MAFw to interface to a DB.

Module Attributes

database_proxy

This is a placeholder for the real database object that will be known only at run time

mafw_model_register

This is the instance of the ModelRegister

Functions

get_db(model_class)

Extract the actual database instance from a model class.

get_primary_key_fields(model_class)

Extract primary key field names and field objects from a model metadata class.

make_prefixed_suffixed_name(model_class)

Generate a table name with optional prefix and suffix for a given model class.

Classes

MAFwBaseModel(*args, **kwargs)

The base model for the MAFw library.

RegisteredMeta(name, bases, attrs, **kwargs)

Metaclass for registering models with the MAFw model registry.

Exceptions

MAFwBaseModelDoesNotExist

Raised when the base model class is not existing.

exception mafw.db.db_model.MAFwBaseModelDoesNotExist[source]

Bases: MAFwException

Raised when the base model class is not existing.

class mafw.db.db_model.MAFwBaseModel(*args, **kwargs)[source]

Bases: Model

The base model for the MAFw library.

Every model class (table) that the user wants to interface must inherit from this base.

This class extends peewee’s Model with several additional features:

  1. Automatic model registration: Models are automatically registered with the MAFw model registry during class definition, enabling dynamic discovery and management of database models.

  2. Trigger support: The class supports defining database triggers through the triggers() method, which are automatically created when the table is created. File removal triggers can also be automatically generated using the file_trigger_auto_create boolean flag in the meta class. See also file_removal_triggers().

  3. Standard upsert operations: Provides std_upsert() and std_upsert_many() methods for performing upsert operations that work with SQLite and PostgreSQL.

  4. Dictionary conversion utilities: Includes to_dict(), from_dict(), and update_from_dict() methods for easy serialization and deserialization of model instances.

  5. Customizable table naming: Supports table name prefixes and suffixes through the Meta class with prefix and suffix attributes. See make_prefixed_suffixed_name().

  6. Automatic table creation control: The automatic_creation Meta attribute controls whether tables are automatically created when the application starts.

Note

The automatic model registration can be disabled for one single model class using the keyword argument do_not_register passed to the RegisteredMeta meta-class. For example:

class AutoRegisterModel(MAFwBaseModel):
    pass


class NoRegisterModel(MAFwBaseModel, do_not_register=True):
    pass

the first class will be automatically registered, while the second one will not. This is particularly useful if the user wants to define a base model class for the whole project without having it in the register where only concrete Model implementations are stored.

DoesNotExist

alias of MAFwBaseModelDoesNotExist

classmethod create_table(safe: bool = True, **options: Any) None[source]

Create the table in the underlying DB and all the related trigger as well.

If the creation of a trigger fails, then the whole table dropped, and the original exception is re-raised.

Warning

Trigger creation has been extensively tested with SQLite, but not with the other database implementation. Please report any malfunction.

Parameters:
  • safe (bool, Optional) – Flag to add an IF NOT EXISTS to the creation statement. Defaults to True.

  • options – Additional options passed to the super method.

classmethod file_removal_triggers() list[Trigger][source]

Generate a list of triggers for automatic file removal when records are deleted.

This method creates database triggers that automatically handle file cleanup when records containing FileNameField fields are removed from the database table. The triggers insert the filenames and checksums into the OrphanFile table for later processing.

The triggers are only created if the model has at least one field of type FileNameField. If no such fields exist, an empty list is returned.

FileNameListField is a subclass of FileNameField and is treated in the same way.

Added in version v2.0.0.

Note

This functionality requires the file_trigger_auto_create attribute in the model’s Meta class to be set to True for automatic trigger creation.

Returns:

A list containing the trigger object for file removal, or an empty list if no FileNameField fields are found.

Return type:

list[Trigger]

classmethod from_dict(data: dict[str, Any], ignore_unknown: bool = False) MAFwBaseModel[source]

Create a new model instance from dictionary

Parameters:
  • data (dict[str, Any]) – The dictionary containing the key/value pairs of the model.

  • ignore_unknown (bool) – If unknown dictionary keys should be ignored.

Returns:

A new model instance.

Return type:

MAFwBaseModel

classmethod get_fields_by_type(field_type: type[Field]) dict[str, Field][source]

Return a dict {field_name: field_object} for all fields of the given type.

Added in version v2.0.0.

Parameters:

field_type (peewee.Field) – Field type

Returns:

A dict {field_name: field_object} for all fields of the given type.

Return type:

dict[str, peewee.Field]

classmethod join_dependent_models(base_query: Select | None = None) Select[source]

Return a query that joins every model referenced through foreign keys.

Each foreign-key relation defined on cls is joined and attached to the resulting rows via an attribute named _<field name> so that callers have the same convenient access that manual .join_from calls would have provided.

Parameters:

base_query (peewee.Select, optional) – Optional query to extend. If not provided a new Select is created that includes cls and the dependent models.

Returns:

The query joining every dependent model.

Return type:

peewee.Select

classmethod std_upsert(_MAFwBaseModel__data: dict[str, Any] | None = None, **mapping: Any) ModelInsert[source]

Perform a so-called standard upsert.

An upsert statement is not part of the standard SQL and different databases have different ways to implement it. This method will work for the three DB backends generating a valid query for the three dialects.

An upsert is a statement in which we try to insert some data in a table where there are some constraints. If one constraint is failing, then instead of inserting a new row, we will try to update the existing row causing the constraint violation.

A standard upsert, in the naming convention of MAFw, is setting the conflict cause to the primary key with all other fields being updated. In other words, the database will try to insert the data provided in the table, but if the primary key already exists, then all other fields will be updated.

This method is equivalent to the following:

class Sample(MAFwBaseModel):
    sample_id = AutoField(
        primary_key=True,
        help_text='The sample id primary key',
    )
    sample_name = TextField(help_text='The sample name')


(
    Sample.insert(sample_id=1, sample_name='my_sample')
    .on_conflict(
        preserve=[Sample.sample_name]
    )  # use the value we would have inserted
    .execute()
)
Parameters:
  • __data (dict, Optional) – A dictionary containing the key/value pair for the insert. The key is the column name. Defaults to None

  • mapping – Keyword arguments representing the value to be inserted.

classmethod std_upsert_many(rows: Iterable[Any], fields: list[str] | None = None) ModelInsert[source]

Perform a standard upsert with many rows.

See also

Read the std_upsert() documentation for an explanation of this method.

Parameters:
  • rows (Iterable) – A list with the rows to be inserted. Each item can be a dictionary or a tuple of values. If a tuple is provided, then the fields must be provided.

  • fields (list[str], Optional) – A list of field names. Defaults to None.

classmethod triggers() list[Trigger][source]

Returns an iterable of Trigger objects to create upon table creation.

The user must overload this returning all the triggers that must be created along with this class.

to_dict(recurse: bool = True, backrefs: bool = False, only: list[str] | None = None, exclude: list[str] | None = None, **kwargs: Any) dict[str, Any][source]

Convert model instance to dictionary with optional parameters

See full documentation directly on the peewee documentation.

Parameters:
  • recurse (bool, Optional) – If to recurse through foreign keys. Default to True.

  • backrefs (bool, Optional) – If to include backrefs. Default to False.

  • only (list[str], Optional) – A list of fields to be included. Defaults to None.

  • exclude (list[str], Optional) – A list of fields to be excluded. Defaults to None.

  • kwargs – Other keyword arguments to be passed to peewee playhouse shortcut.

Returns:

A dictionary containing the key/value of the model.

Return type:

dict[str, Any]

update_from_dict(data: dict[str, Any], ignore_unknown: bool = False) MAFwBaseModel[source]

Update current model instance from dictionary

The model instance is returned for daisy-chaining.

Parameters:
  • data (dict[str, Any]) – The dictionary containing the key/value pairs of the model.

  • ignore_unknown (bool) – If unknown dictionary keys should be ignored.

class mafw.db.db_model.RegisteredMeta(name: str, bases: tuple[type, ...], attrs: dict[str, Any], **kwargs: dict[str, Any])[source]

Bases: ModelBase

Metaclass for registering models with the MAFw model registry.

This metaclass automatically registers model classes with the global model registry when they are defined, allowing for dynamic discovery and management of database models. It ensures that only concrete model classes (not the base classes themselves) are registered.

The registration process uses the table name from the model’s metadata or generates a snake_case version of the class name if no explicit table name is set.

Create a new model class and register it if applicable.

This method is called during class definition to create the actual class and register it with the MAFw model registry if it’s a concrete model class.

Parameters:
  • name (str) – The name of the class being created.

  • bases (tuple) – The base classes of the class being created.

  • attrs (dict) – The attributes of the class being created.

  • kwargs (dict[str, Any]) – Other keyword attributes passed to the class.

Returns:

The newly created class.

Return type:

type

mafw.db.db_model.get_db(model_class: PeeweeModelWithMeta) Database[source]

Extract the actual database instance from a model class.

This function retrieves the database object from a model class’s metadata, handling the case where the database is a peewee.DatabaseProxy. If the database is a proxy, it extracts the underlying database object.

Parameters:

model_class (PeeweeModelWithMeta) – The model class from which to extract the database.

Returns:

The actual database instance.

Return type:

Database

mafw.db.db_model.get_primary_key_fields(model_class: PeeweeModelWithMeta) tuple[list[str], list[Field]][source]

Extract primary key field names and field objects from a model metadata class.

This function retrieves the primary key information from a Peewee model metadata class, handling both single-column primary keys and composite (multi-column) keys. It returns two parallel lists: the first containing the field names as strings, and the second containing the corresponding field objects.

Parameters:

model_class (RegisteredMeta) – The model class from which to extract primary key information.

Returns:

A tuple containing two lists: the first with primary key field names (as strings) and the second with the corresponding field objects.

Return type:

tuple[list[str], list[Field]]

mafw.db.db_model.make_prefixed_suffixed_name(model_class: RegisteredMeta) str[source]

Generate a table name with optional prefix and suffix for a given model class.

This function constructs a table name by combining the prefix, the snake_case version of the model class name, and the suffix. If either prefix or suffix are not defined in the model’s metadata, empty strings are used instead.

The prefix, table name, and suffix are joined using underscores. For example:

  • If a model class is named “UserAccount” with prefix=”app”, suffix=”data”, the resulting table name will be “app_user_account_data”

  • If a model class is named “Product” with prefix=”ecommerce”, suffix=”_latest”, the resulting table name will be “ecommerce_product_latest”

Note

Underscores (_) will be automatically added to prefix and suffix if not already present.

Parameters:

model_class (RegisteredMeta) – The model class for which to generate the table name.

Returns:

The constructed table name including prefix and suffix if applicable.

Return type:

str

mafw.db.db_model.database_proxy = <peewee.DatabaseProxy object>

This is a placeholder for the real database object that will be known only at run time

mafw.db.db_model.mafw_model_register = <mafw.db.model_register.ModelRegister object>

This is the instance of the ModelRegister

See also

ModelRegister for more information on how to retrieve models and RegisteredMeta and MAFwBaseModel for the automatic registration of models`