migrations
GitHub用于生成、审查、编辑和应用 Drizzle 数据库迁移,处理迁移冲突及 schema 变更。遵循自动生成 SQL 原则,规范命名与版本追踪,确保数据库结构安全同步。
Trigger Scenarios
Install
npx skills add theopenco/llmgateway --skill migrations -g -y
SKILL.md
Frontmatter
{
"name": "migrations",
"description": "Generate, review, edit, apply, or resolve conflicts for Drizzle database migrations in this repo. Use when changing packages\/db\/src\/schema.ts, running pnpm migrations or pnpm migrate, touching packages\/db\/migrations, reviewing migration diffs, or handling migration merge conflicts."
}
Migrations
Use this workflow for database schema changes and migration conflicts.
Default: use generated SQL
Assume Drizzle applies migrations cleanly and tracks which have run. Generate, review, and commit the migration without adapting its SQL by default.
Do not add IF NOT EXISTS, IF EXISTS, existence probes, or duplicate-object
handlers for hypothetical reruns, partial application, or schema drift.
Regenerating an unmerged migration after syncing with main does not justify
compatibility with its earlier branch version. A speculative review warning is
not evidence that a migration ran outside the normal workflow.
How Drizzle tracks migrations
- Each migration is a folder
packages/db/migrations/<YYYYMMDDHHMMSS>_<name>/holdingmigration.sqlandsnapshot.json. - The migrator records each applied folder name in
drizzle.__drizzle_migrations.nameand applies every local folder whose name is missing, regardless of timestamp. A branch migration older than migrations already onmainstill runs after merge. - The folder name is the tracking key: never rename or delete a merged migration folder. A renamed folder runs again.
- Each
snapshot.jsonlists its parents inprevIds.drizzle-kitfollows that graph, and an open leaf merges into the next generated diff, so a snapshot with a wrong parent makespnpm migrationsemit destructive DROPs.
Generate migrations
- Run all commands from the repository root.
- CI allows at most one new migration per PR (
scripts/check-new-migrations.sh). For follow-up schema changes, delete and regenerate the PR’s unmerged migration instead of adding another; never delete a merged migration. - Make schema changes in
packages/db/src/schema.ts. Tables usesnakeCase.table, which maps camelCase fields to snake_case columns. - Generate the migration with
pnpm migrations --name <name>. It also runs the commutativity check below. - Name it after the change in snake_case, at most four words:
<table>_<column>for an added column,<table>for a new table,<index_name>for an index, and adrop_orrename_prefix for destructive changes (project_description,api_key_status_idx,drop_transaction_note). Never keep Drizzle's random default name. - If one migration mixes changes, name the destructive one; if that is unclear, split the schema change into separate migrations.
- Review the new
packages/db/migrations/<timestamp>_<name>/folder; confirm the SQL matches the name.
Editing generated migrations
- Do not write a migration by hand from scratch. Generate it first with
pnpm migrations --name <name>. - The operational exception is avoiding locks on huge tables, especially when creating indexes. Treat all history tables as large when reviewing locking behavior.
- If that requires adaptation, edit only the generated
migration.sql. - Never manually edit any
snapshot.json. - If the TypeScript schema is wrong, fix
packages/db/src/schema.tsand regenerate instead of patching snapshots. - Use snake_case column names in SQL.
For a large-table index change, a staged rollout may require splitting the
change into two generated migrations and running CREATE INDEX CONCURRENTLY
manually between them, outside a transaction. Document the required order in
the SQL. Keep the generated snapshots exactly as Drizzle wrote them.
Syncing with main
Migration folders from different branches do not conflict in git. After merging main, run:
pnpm migrations:check
It reports non-commutative migrations: branch migrations that touch the same objects as migrations merged to main since the branch point. If it passes, keep the branch migration as-is. If it fails, regenerate the branch migration on top of main:
- Note any locking adaptation in your branch's
migration.sql; regeneration emits vanilla SQL and drops it. - Delete your branch's migration folder, then run
pnpm migrations --name <same name>. - Re-apply only still-required locking adaptations. Do not carry speculative fallbacks forward.
Never resolve conflicts in migration SQL or snapshot JSON by hand.
Validation
- Inspect
git diff packages/db/src/schema.ts packages/db/migrations/. - Confirm snapshot changes came from
pnpm migrations, not manual edits. - Run
pnpm formatafter changes. - Run
pnpm buildafter schema or migration changes.
Version History
-
d41bf19
Current 2026-10-19 04:13
新增迁移跟踪机制说明(基于文件夹名和 snapshot.json prevIds),细化 CI 单 PR 限制及命名规范,明确禁止手动编辑 snapshot.json。
-
bf6473c
2026-09-09 03:58
修正迁移指南中不必要的防御性 SQL,默认信任生成的 Drizzle SQL,拒绝推测性兼容性保护,并文档化大表和历史表的并发索引创建作为操作异常。
- 8fdff5b 2026-08-16 07:59
- 8c03315 2026-07-24 16:53


