Database Evolution
The Camera Manager service operates with a high degree of autonomy, including the management of its own database schema. This page details the Declarative Migration System used to ensure the database structure is always aligned with the code.
Why Internal Migrations?
In a distributed microservices architecture, the camera-manager might be deployed independently of the backend API. To avoid dependency on external migration tools (like AdonisJS Ace or Alembic) and to ensure robust self-healing, the service includes a lightweight, built-in migration engine.
Declarative System
Instead of writing procedural migration scripts ("do this, then do that"), we define the Desired State of the schema in src/database.py.
# database.py
SCHEMA_EVOLUTION = [
{
"table": "running_scripts",
"add_columns": [
("status_updated_at", "TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"),
],
"drop_columns": [
"runtime_seconds",
]
}
]
How It Works
On startup, the ensure_schema_updates() function runs automatically:
- Inspection: It inspects the
information_schemato see what columns currently exist for each table. - Convergence:
- Missing Columns: If a column in
add_columnsis missing, it executes anALTER TABLE ... ADD COLUMNcommand. - Obsolete Columns: If a column in
drop_columnsexists, it executes anALTER TABLE ... DROP COLUMNcommand.
- Missing Columns: If a column in
- Idempotency: The system checks before acting. If the schema is already correct, it does nothing. This makes it safe to run on every boot.
Migration Process
- Developer adds a new column to
SCHEMA_EVOLUTION. - Deployment of the new container image.
- Startup: The service detects the schema difference and applies the fix.
- Ready: The service starts processing cameras with the correct DB structure.