Database and Migrations¶
ChaCC API uses SQLAlchemy for database access and Alembic comparison utilities for automatic migrations. The migration runner tracks applied operations so migrations are not repeated.
Database engines¶
| Engine | Use case | Notes |
|---|---|---|
| SQLite | Local development and simple deployments | Stores chaccapi.db in the current working directory. |
| PostgreSQL | Production | Uses native UUID and requires full connection settings. |
Base model¶
Import the base model and register each table model:
from chacc_api import ChaCCBaseModel, register_model
from sqlalchemy import Column, String
@register_model
class Project(ChaCCBaseModel):
__tablename__ = "projects"
name = Column(String, nullable=False)
The generated table name defaults to the class name in lowercase plus s, unless
__tablename__ is set.
GUID type¶
The GUID type decorator stores UUIDs as native PostgreSQL UUID values and as
36-character strings on SQLite and other databases. It returns Python uuid.UUID
instances from the database.
Timestamps¶
ChaCCBaseModel uses SQLAlchemy events to set:
created_aton insert when missing.updated_aton insert and update.
Migration modes¶
| Mode | Behavior |
|---|---|
preview |
Compares metadata and returns pending operations without applying them. |
auto |
Applies safe operations and filters destructive operations. |
full |
Applies all detected operations, including destructive operations. |
Safe operations include adding tables, adding columns, adding indexes, adding constraints, creating foreign keys, modifying types, modifying nullability, modifying defaults, and enum synchronization.
Destructive operations such as dropping tables are skipped in auto mode.
Migration lifecycle¶
flowchart TD
A[Discover @register_model classes] --> B[Compare metadata with database]
B --> C[Filter operations by MIGRATION_MODE]
C --> D{Backup enabled?}
D -->|Yes| E[Create backup]
D -->|No| F[Apply migrations]
E --> F
F --> G[Record migration in chacc_migration_log]
Backup and restore¶
Enable backups with:
SQLite backups copy the database file. PostgreSQL backups use pg_dump and
restore through psql.
Backup files are named with timestamps:
- SQLite:
chacc_backup_YYYYMMDD_HHMMSS.db - PostgreSQL:
chacc_backup_YYYYMMDD_HHMMSS.sql
Migration tracker table¶
The runner creates chacc_migration_log to record applied migrations.
| Column | Type | Purpose |
|---|---|---|
id |
Integer / serial | Internal row id. |
version_num |
String | Unique migration version. |
description |
Text | Human-readable operation summary. |
checksum |
String | Checksum for the operation details. |
applied_at |
Timestamp | Application time. |
rollback_available |
Integer | Rollback marker. |
The tracker table is excluded from destructive drop detection so it is not accidentally removed by schema comparison.
Idempotency¶
The runner catches ProgrammingError and OperationalError messages containing
already exists or duplicate, allowing repeated startup migrations to complete
without failing when resources already exist.
SQLite compatibility¶
SQLite migrations use batch_alter_table() for column, type, nullability,
default, index, and constraint changes. This avoids common SQLite limitations
around direct table alteration.