Skip to content

fix: init-db checks aerich table instead of migrations folder (#267)#526

Merged
waketzheng merged 3 commits intotortoise:devfrom
teochenglim:fix/init-db-check-aerich-table
Mar 1, 2026
Merged

fix: init-db checks aerich table instead of migrations folder (#267)#526
waketzheng merged 3 commits intotortoise:devfrom
teochenglim:fix/init-db-check-aerich-table

Conversation

@teochenglim
Copy link
Contributor

Description

Fixes #267

What changed

aerich init-db previously checked whether the migrations folder existed to decide if the app was already initialised. This caused a false positive when migration files were committed to a repo: new developers (or CI servers) running aerich init-db against a fresh database would get:

App 'models' is already initialized. Delete migrations/models and try again. 

The fix replaces the folder check with a database-side check: aerich init-db now queries the aerich tracking table to determine prior initialisation.

New behaviour

Situation Before After
Fresh DB, no migration folder ✅ Creates folder + initial migration ✅ Same
Fresh DB, migration files exist (cloned repo) ❌ "Already initialized" error ✅ Applies all migrations in order
DB already initialised (aerich table has records) ✅ "Already initialized" warning ✅ Same

Usage

# Developer 2 clones the repo (migrations/ already committed) and runs: aerich init-db # Applied existing migrations to database for app "models" # Success writing schemas to database "db.sqlite3"
@teochenglim
Copy link
Contributor Author

Why this fix matters — Aerich migration workflow

The intended workflow (now works correctly)

Aerich is designed to work like Django migrations or Go ORM (GORM AutoMigrate + goose):
migration files live in the repo, and any environment — local, CI, staging, production — can
reach the current database state by running a single command.


Local development

# 1. Start local database docker compose up -d # 2. First time only — initialise aerich and create the first migration aerich init -t your_app.config.TORTOISE_ORM aerich init-db # creates migrations/models/0_..._init.py AND applies it locally # 3. After changing your models aerich migrate --name add_user_email # generates migrations/models/1_..._add_user_email.py aerich upgrade # apply locally to verify it works # 4. Commit the generated migration files git add migrations/ git commit -m "add user email field" git push

The migrations/ folder is committed to the repository — just like Django's migrations/
or Go's migration SQL files.


Another developer onboards (the bug this PR fixes)

Before this fix, a new developer who cloned the repo would hit a confusing error:

App 'models' is already initialized. Delete migrations/models and try again. 

This happened because aerich was checking whether the folder existed, not whether the
database had been initialised.

After this fix:

# Developer 2 clones the repo — migrations/ is already there from git git clone https://github.com/your-org/your-app.git docker compose up -d aerich init-db # Applied existing migrations to database for app "models" # Success writing schemas to database "db.sqlite3" # From this point, normal workflow applies: aerich upgrade # picks up any migrations added since the clone

Server / CI / GitOps

# First deploy to a fresh environment aerich init-db # applies all migrations in order, marks them as applied # Every subsequent deploy (GitOps / CD pipeline) aerich upgrade # only runs migrations not yet recorded in the aerich table

aerich init-db is now safe to call idempotently in a fresh environment:

  • No aerich table → applies all migration files in order (new behaviour)
  • aerich table exists → reports "already initialized", does nothing (safe to call)
  • No migration folder → creates it and generates the first migration (original behaviour)

Comparison with other frameworks

Framework "init new env" command "apply pending" command
Django python manage.py migrate python manage.py migrate
Alembic alembic upgrade head alembic upgrade head
golang-migrate migrate up migrate up
Aerich (after fix) aerich init-db → then aerich upgrade aerich upgrade

All of them share the same principle: migration files are the source of truth, committed to
the repository, and applied in order on any environment that needs the database.

@teochenglim
Copy link
Contributor Author

in order to workaround the bug
https://github.com/teochenglim/aerich-orm-play

@waketzheng waketzheng merged commit 7a1f510 into tortoise:dev Mar 1, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants