Alembic Golden Rule
Published on: 24 September 2025
Tags: #alembic #database #migration
The Golden Rule Decision Flowchart
graph TD
A[Start: You've created a new
migration script] --> B["Has the migration been
applied to a shared DB
(e.g., staging, prod)?"];
B -- No, only on local --> C[It's safe to edit the
migration script];
B -- Yes --> D[STOP!
Do NOT edit the
original script];
D --> E[Create a new migration
script to fix the issue];
E --> F[Apply the new script to
all environments];
C --> G[Finalize and commit
the script];
F --> H[Problem solved,
history is preserved];
G --> H;
style D fill:#ffbaba,stroke:#ff0000,stroke-width:2px
The Danger of Breaking the Rule
sequenceDiagram
participant DevA as Developer A
participant Git
participant SharedDB as Shared Database (Staging)
participant DevB as Developer B
DevA->>Git: Pushes migration V1_add_user_table.py
Git-->>SharedDB: CI/CD applies V1
note right of SharedDB: DB is now at version V1
DevA->>DevA: Realizes a mistake in V1
DevA->>Git: Force-pushes an edited version of V1_add_user_table.py
note right of DevA: This is the rule violation!
DevB->>Git: Pulls the latest code (with edited V1)
DevB->>DevB: Runs alembic upgrade head
note right of DevB: Alembic checks SharedDB, sees V1 is already applied.
It skips the migration, assuming no changes are needed.
DevB->>SharedDB: Deploys new application code that depends on the *edited* V1
SharedDB-->>DevB: ERROR!
Application crashes because the database schema
doesn't match what the code expects.
Correct vs. Incorrect Migration Workflows
stateDiagram-v2
direction TB
state "Correct Workflow (Immutable History)" as Correct {
[*] --> V1 : Create `V1_add_table`
V1 --> V2 : Apply V1, then create
`V2_add_column`
V2 --> V3 : Realize mistake in V2,
create `V3_fix_V2_column`
V3 --> [*] : Schema is consistent and
history is clear
}
state "Incorrect Workflow (Rewriting History)" as Incorrect {
[*] --> V1_Original: Create `V1_add_table`
V1_Original --> StagingDB: Apply V1 (Original) to
Staging
V1_Original --> V1_Edited: Developer edits V1 locally
V1_Edited --> DevDB: Developer applies V1
(Edited) to Local DB
state "Divergent States" as Divergence {
StagingDB --> InconsistentStaging: Code expects V1_Edited but
DB has V1_Original
DevDB --> InconsistentDev: Works locally, but out of
sync with shared environments
}
InconsistentStaging --> CHAOS
InconsistentDev --> CHAOS
}