mafw.db.migration.directory

Migration-directory resolution and exclusive locking.

The effective migration directory is resolved with a fixed precedence — a CLI override, then a SchemaMigrator ActiveParameter, then the steering-file database-configuration value, then a documented default. A relative effective directory is resolved against a single stable base directory (the steering file’s directory) so that identical input always yields the same absolute path.

Two exclusive locks keep concurrent processes from corrupting shared state: a filesystem lock guards script writes in the directory, and a database advisory lock guards history mutations. Each lock either acquires (waiting if needed) or fails with a “locked” error, leaving history and scripts unaffected by a blocked process.

Added in version 2.4.

author:

Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)

Module Attributes

DEFAULT_MIGRATION_DIRECTORY

The documented default migration directory name, relative to the stable base.

Functions

database_lock(database)

Acquire an exclusive lock on the database before mutating the history.

directory_lock(directory, *[, timeout, poll])

Acquire an exclusive filesystem lock on the migration directory.

resolve_directory(*, cli_override, ...[, ...])

Resolve the effective migration directory following the fixed precedence.

validate_directory(directory)

Ensure the resolved directory exists and is a readable directory.

Exceptions

MigrationLockError

Raised when an exclusive migration lock cannot be acquired.

exception mafw.db.migration.directory.MigrationLockError[source]

Bases: MigrationError

Raised when an exclusive migration lock cannot be acquired.

Added in version 2.4.

mafw.db.migration.directory.database_lock(database: Database) → Iterator[None][source]

Acquire an exclusive lock on the database before mutating the history.

The lock is implemented with the backend’s native transaction/locking facilities through peewee.Database.atomic(), which begins an exclusive transaction on the supported backends. If the backend reports the database is busy, a MigrationLockError is raised and the history is left unchanged.

Parameters:

database (peewee.Database) – The database to lock.

Raises:

MigrationLockError – when the database is locked by another process.

mafw.db.migration.directory.directory_lock(directory: Path, *, timeout: float = 30.0, poll: float = 0.1) → Iterator[None][source]

Acquire an exclusive filesystem lock on the migration directory.

The lock is a sentinel file created with O_CREAT | O_EXCL. The context manager waits up to timeout seconds for a competing holder to release the lock; if the timeout elapses it raises MigrationLockError without writing any script.

Parameters:
  • directory (Path) – The directory to lock.

  • timeout (float) – The maximum number of seconds to wait for the lock.

  • poll (float) – The polling interval in seconds while waiting.

Raises:

MigrationLockError – when the lock cannot be acquired within the timeout.

mafw.db.migration.directory.resolve_directory(*, cli_override: Path | str | None, active_parameter: Path | str | None, steering_value: Path | str | None, base: Path, default: str = 'migrations') → Path[source]

Resolve the effective migration directory following the fixed precedence.

Precedence (highest first): CLI override, SchemaMigrator ActiveParameter, steering-file value, documented default.

The effective value may be either absolute or relative:

  • an absolute path is used as given (only normalised with resolve()), independent of the base directory;

  • a relative path is resolved against base deterministically to one absolute path, so identical input always yields the same result.

A leading ~ is expanded to the user’s home directory before the absolute/relative distinction is applied.

This function does not touch the filesystem beyond path resolution; use validate_directory() to check that the resolved directory exists.

Parameters:
  • cli_override (Path | str | None) – The CLI override value, if provided.

  • active_parameter (Path | str | None) – The processor ActiveParameter value, if set.

  • steering_value (Path | str | None) – The steering-file database-configuration value.

  • base (Path) – The stable base directory for resolving a relative value.

  • default (str) – The documented default directory name.

Returns:

The resolved absolute directory path.

Return type:

Path

mafw.db.migration.directory.validate_directory(directory: Path) → Path[source]

Ensure the resolved directory exists and is a readable directory.

Parameters:

directory (Path) – The resolved directory to validate.

Returns:

The validated directory.

Return type:

Path

Raises:

MigrationUnresolvedDirectoryError – when the directory does not exist or is not a directory.

mafw.db.migration.directory.DEFAULT_MIGRATION_DIRECTORY = 'migrations'

The documented default migration directory name, relative to the stable base.

mafw.db.migration.directory._DIRECTORY_LOCK_FILE = '.mafw-migration.lock'

The lock file name created inside the migration directory.