| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Invoke | /serverpod:merge-migrations |
| Category | serverpod |
| Complexity | moderate |
/serverpod:merge-migrations โ ํฉ์ด์ง DB ๋ณ๊ฒฝ ๊ธฐ๋ก์ ํ๋๋ก ํฉ์น๊ธฐ#
ํ๋ง๋๋ก#
๊ฐ๋ฐํ๋ฉด์ ์กฐ๊ธ์ฉ ์์ธ ์ฌ๋ฌ ๊ฐ์ "DB ๋ณ๊ฒฝ ๊ธฐ๋ก(๋ง์ด๊ทธ๋ ์ด์ )"์ ํ๋๋ก ๊น๋ํ๊ฒ ๋ฌถ์ด์ฃผ๋ ์ ๋ฆฌ ๋๊ตฌ์ ๋๋ค. ์ฌ๋ฌ ์ฅ์ผ๋ก ์ฐข์ด์ง ์์์ฆ์ ํ ์ฅ์ผ๋ก ์ ๋ฆฌํด ๋๋ ๊ฒ๊ณผ ๊ฐ์์. ์ด์(์ค์๋น์ค) ์๋ฒ์๋ ์๋์ง ์๊ณ , ๊ฐ๋ฐ ํ๊ฒฝ์์๋ง ์ ๋ฆฌํฉ๋๋ค.
๋๊ฐยท์ธ์ ์ฐ๋์#
- ๊ฐ๋ฐ ์ค์ DB ๊ตฌ์กฐ ๋ณ๊ฒฝ ๊ธฐ๋ก์ด ์ฌ๋ฌ ๊ฐ๋ก ์๊ฒ ์์ฌ์, ์ค์๋น์ค ๋ฐฐํฌ ์ ์ ๊น๋ํ๊ฒ ์ ๋ฆฌํ๊ณ ์ถ์ ๋
- ๋ง์ด๊ทธ๋ ์ด์ ํ์คํ ๋ฆฌ(๋ณ๊ฒฝ ์ด๋ ฅ)๊ฐ ์ง์ ๋ถํด์ ๋ณด๊ธฐ ์ข๊ฒ ํฉ์น๊ณ ์ถ์ ๋
๐ ๋ฐฑ์๋(Serverpod) ๊ฐ๋ฐ์๊ฐ ์ฃผ๋ก ์ฌ์ฉํ๋ฉฐ, ์ด๋ฏธ ์ด์ ์๋ฒ์ ๋ฐ์๋ ๊ธฐ๋ก์ ๊ฑด๋๋ฆฌ์ง ์๊ณ ๊ทธ ์ดํ์ ์๊ธด ๊ฐ๋ฐ์ฉ ๊ธฐ๋ก๋ค๋ง ํฉ์นฉ๋๋ค.
๋ฌด์์ ํด์ฃผ๋์#
์ฌ๋ฌ ๊ฐ๋ก ๋๋ ๋ง์ด๊ทธ๋ ์ด์ ์ ํ๋์ ์ ๋ง์ด๊ทธ๋ ์ด์ ์ผ๋ก ํฉ์ณ์ค๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก:
- ํฉ์น๊ธฐ ์ ์ ๊ธฐ์กด ๋ง์ด๊ทธ๋ ์ด์
์
migrations_backup/ํด๋์ ์๋ ๋ฐฑ์ - ์๋ก ํฉ์ณ์ง ๋ง์ด๊ทธ๋ ์ด์
ํด๋ 1๊ฐ ์์ฑ (๊ทธ ์์
definition.sql,migration.sql๋ฑ ์ค์ ํ์ผ๋ค) - ๋ณ๊ฒฝ ์ด๋ ฅ ๋ชฉ๋ก ํ์ผ์ธ
migration_registry.txt์๋ ๊ฐฑ์ - ์ด์ ์๋ฒ์ ์ด๋ฏธ ๋ฐ์๋ ๊ธฐ์ค ๋ง์ด๊ทธ๋ ์ด์
(
--base)์ ๊ทธ๋๋ก ๋ณด์กด
์ด๋ป๊ฒ ์ฐ๋์#
# ๊ธฐ๋ณธ: ๊ธฐ์ค(--base) ์ดํ์ ์๊ธด ๋ชจ๋ ๋ง์ด๊ทธ๋ ์ด์
์ ์๋์ผ๋ก ์ฐพ์ ํฉ์น๊ธฐ
/serverpod:merge-migrations --base 20251223123500000
# ํฉ์น ๋ฒ์๋ฅผ ์ง์ ์ง์ (์์~๋)
/serverpod:merge-migrations \
--base 20251223123500000 \
--from 20251229134213396 \
--to 20260113023207235
# ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ง (์ค์ ๋ก ๋ฐ๊พธ์ง ์๊ณ ๊ฒฐ๊ณผ๋ง ํ์ธ)
/serverpod:merge-migrations --base 20251223123500000 --dry-run
-
--base(ํ์): ์ด์ ์๋ฒ์ ์ด๋ฏธ ์ ์ฉ๋ ๊ธฐ์ค ๋ง์ด๊ทธ๋ ์ด์ ID. ์ด ID๋ ์ ๋ ๊ฑด๋๋ฆฌ์ง ์์ผ๋ฉฐ, ์ด ์์ ์ดํ์ ๊ฐ๋ฐ์ฉ ๊ธฐ๋ก๋ง ์ ๋ฆฌ ๋์์ด ๋ฉ๋๋ค. --from/--to: ํฉ์น ์์ยท๋ ์ง์ . ๋น์๋๋ฉด ์๋์ผ๋ก ์ก์์ค๋๋ค.--name: ํฉ์ณ์ง ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ถ์ผ ์ด๋ฆ.--dry-run: ์ค์ ๋ณ๊ฒฝ ์์ด ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ง ํฉ๋๋ค.
์์์ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์#
- ๋ถ์ โ ๊ธฐ์ค(
--base) ์ดํ์ ์๊ธด ๋ง์ด๊ทธ๋ ์ด์ ๋ค์ ๋ชจ์, ์ด๋ค ํ ์ด๋ธ์ด ๋ฐ๋๋์ง ํ๋ก ๋ณด์ฌ์ค๋๋ค. - ํฉ์น๊ธฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ โ ํฉ์ด์ง ๋ณ๊ฒฝ ๋ด์ฉ(SQL)์ ํ๋๋ก ํฉ์ณค์ ๋ ์ด๋ป๊ฒ ๋๋์ง ๋ฏธ๋ฆฌ ๋ณด์ฌ์ค๋๋ค.
- ์ฌ์ฉ์ ํ์ธ โ "๊ธฐ์กด ํ์ผ์ด ์ญ์ ๋๊ณ ๋ก์ปฌ์์๋ง ์คํ๋๋ค"๋ ์ฃผ์์ฌํญ์ ์๋ดํ๊ณ , ์งํํ ์ง(Y/n) ๋ฌผ์ด๋ด ๋๋ค.
- ์คํ โ ๊ธฐ์กด ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ฐฑ์ ํ ๋ค ์ญ์ ํ๊ณ , ํฉ์ณ์ง ์ ๋ง์ด๊ทธ๋ ์ด์ ์ ๋ง๋ค๊ณ , ์ด๋ ฅ ๋ชฉ๋ก์ ๊ฐฑ์ ํฉ๋๋ค.
- ๊ฒ์ฆ โ ํฉ์น๊ธฐ ์๋ฃ ๊ฒฐ๊ณผ์ ๋ฐฑ์ ์์น, ๋ค์์ ํ ์ผ(๋ก์ปฌ DB ์ฌ์ค์ ยท์ปค๋ฐ)์ ์๋ ค์ค๋๋ค.
์ด์ ์๋ฒ๋ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค. ์ด์ DB๋ ์ด๋ฏธ ์ ์ฉ๋ ๊ธฐ๋ก์ ๋ฐ๋ก ๊ด๋ฆฌ(serverpod_migrations ํ
์ด๋ธ)ํ๊ธฐ ๋๋ฌธ์ด๋ฉฐ, ํฉ์ณ์ง ๋ง์ด๊ทธ๋ ์ด์
์ ์ ํ๊ฒฝ์์๋ง ์ฐ์
๋๋ค. ๋ค๋ฅธ ํ์๊ณผ ๋์์ ์์
ํ๋ฉด ์ถฉ๋์ด ์๊ธธ ์ ์์ผ๋, ํฉ์น๊ธฐ ์ ์ ํ์๊ณผ ์กฐ์จํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
โ๏ธ ์์ธ ์ต์ ยท์คํ ๋ช ์ธ (๊ฐ๋ฐ์ / AI ์์ด์ ํธ์ฉ)
Triggers#
- When cleaning up migrations before production deployment
- When consolidating multiple development migrations into one
- When cleaning up migration history
Context Trigger Pattern#
/serverpod:merge-migrations --base {production_migration} [--options]Parameters#
| Parameter | Required | Description | Example |
|---|---|---|---|
--base | โ | Production baseline migration ID (this ID is preserved) | 20251223123500000 |
--from | โ | Merge start migration (auto-detected after base if not specified) | 20251229134213396 |
--to | โ | Merge end migration (auto-detected as latest if not specified) | 20260113023207235 |
--name | โ | Merged migration name | consolidated_dev |
--dry-run | โ | Preview only without actual changes | true/false |
Note:
--baseis always required. Specify the production-applied migration ID to only merge development migrations after that point.
Behavioral Flow#
Step 1: Migration Analysis#
## Migration Analysis
**Production baseline**: {base_migration}
**Merge targets**: {count}
| # | Migration ID | Created | Changed Tables |
|---|-------------|---------|----------------|
| 1 | 20251229134213396 | 2025-12-29 | coupon |
| 2 | 20260112140301453 | 2026-01-12 | author |
| 3 | 20260113023207235 | 2026-01-13 | author |
**Affected tables**: coupon, authorStep 2: SQL Merge#
## SQL Merge Preview
### Before merge (individual migrations)-- Migration 1: 20251229134213396 ALTER TABLE "coupon" ADD COLUMN "new_field" text;
-- Migration 2: 20260112140301453 ALTER TABLE "author" ADD COLUMN "memo" text;
-- Migration 3: 20260113023207235 ALTER TABLE "author" ADD COLUMN "extra" text;
### After merge (single migration)-- Migration: {new_migration_id} BEGIN;
ALTER TABLE "coupon" ADD COLUMN "new_field" text; ALTER TABLE "author" ADD COLUMN "memo" text; ALTER TABLE "author" ADD COLUMN "extra" text;
-- MIGRATION VERSION FOR kobic INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('kobic', '{new_migration_id}', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '{new_migration_id}', "timestamp" = now();
COMMIT;
Step 3: User Confirmation#
## Merge Confirmation
**Caution**:
- This operation deletes existing migration files
- Run only on local development DB
- Existing migrations must already be applied to the production DB
**Proceed with merge? (Y/n)**Step 4: Execute Merge#
# 1. Backup existing migrations
mkdir -p migrations_backup
for dir in migrations/{from} migrations/{middle} migrations/{to}; do
cp -r " $dir " migrations_backup/
done
# 2. Delete existing migrations
rm -rf migrations/{from}
rm -rf migrations/{middle}
rm -rf migrations/{to}
# 3. Create new migration
serverpod create-migration --experimental-features=all
# 4. Update migration_registry.txt
# Remove old migration IDs, add new IDStep 5: Verification#
## Merge Complete
Existing migrations backed up: `migrations_backup/`
New migration created: `{new_migration_id}`
migration_registry.txt updated
### Next Steps
1. **Reset local DB** (optional):
Recreate local DB from scratch#
melos run backend:pod:run-migration
2. **Commit changes**:
git add backend/kobic_server/migrations/ git commit -m "chore(migration): merge migrations ({from}~{to} โ {new_id})"
### Backup Location
Existing migrations are stored in `migrations_backup/`Output Files#
backend/kobic_server/
โโโ migrations/
โ โโโ {base_migration}/ # Production (preserved)
โ โโโ {new_migration}/ # Newly created merged migration
โ โ โโโ definition.json
โ โ โโโ definition.sql
โ โ โโโ definition_project.json
โ โ โโโ migration.json
โ โ โโโ migration.sql
โ โโโ migration_registry.txt # Updated
โโโ migrations_backup/ # Backup (can be deleted)
โ โโโ {old_migration_1}/
โ โโโ {old_migration_2}/
โ โโโ ...Manual Merge Guide (Instead of Script)#
If the skill does not auto-execute, follow these steps manually:
1. Check Current State#
# Check migration_registry.txt
cat backend/kobic_server/migrations/migration_registry.txt
# Check post-production migrations
ls -la backend/kobic_server/migrations/ | grep " 2026 "2. Backup and Delete Existing Migrations#
cd backend/kobic_server
# Backup
mkdir -p migrations_backup
mv migrations/20251229134213396 migrations_backup/
mv migrations/20260112140301453 migrations_backup/
mv migrations/20260113023207235 migrations_backup/
# Remove the corresponding lines from migration_registry.txt
# Manually edit to remove the migration IDs to be deleted3. Create New Migration#
# Code generation (based on current models)
melos run backend:pod:generate
# Create new migration
melos run backend:pod:create-migration4. Verify#
# Check new migration
ls -la backend/kobic_server/migrations/ | tail -5
# Check migration_registry.txt
tail backend/kobic_server/migrations/migration_registry.txtExamples#
Basic usage (production baseline)#
Auto-detect and merge all migrations after --base:
/serverpod:merge-migrations --base 20251223123500000Range specification#
Merge specific range based on --base (after base ~ to):
/serverpod:merge-migrations \
--base 20251223123500000 \
--from 20251229134213396 \
--to 20260113023207235Dry-run (preview)#
Preview merged content without actual changes:
/serverpod:merge-migrations --base 20251223123500000 --dry-runCore Rules#
- Production baseline: Do not touch production-applied migrations
- Backup required: Always backup before deletion
- Local only: Never run on production DB
- Order preserved: Migration order is automatically managed by timestamp
- Verification required: Verify with
melos run backend:pod:generateafter merge
Cautions#
Production DB caution:
- Existing migrations are already applied to the production DB
- Merged migrations are only used in new environments
- Existing production is unaffected (references serverpod_migrations table)
Team collaboration:
- Migration conflicts possible with other developers
- Coordinate with team members before merging
- Check migration_registry.txt conflicts before PR merge