GS
Opens language menu

Database & migrations

The starter treats schema changes as first-class code: each migration is a Go file registered in a central list, with status, rollback, and create helpers exposed through CLI flags and Makefile targets.

Why not only AutoMigrate?

AutoMigrate is convenient in demos but weak for production:

  • Hard to review schema diffs in pull requests.
  • Hard to rollback precisely when a deploy goes wrong.
  • Teams lose a chronological history tied to application releases.

Numbered migration files give you an audit trail similar to frameworks you may know from other languages.

File layout

PathMeaning
database/migrations/*.goOne logical change per file (or tightly related changes).
database/migration.goRegisters available migrations with the runner.
database/manager.goUser-facing operations: run, rollback, status, scaffold new file.
database/entities/*.goGORM models representing tables.

Keep migration order compatible with existing data — avoid destructive operations without a follow-up data migration plan.

Running migrations

Apply all pending

go run cmd/main.go --migrate:run

Equivalent shorthand may exist as --migrate depending on parser in script/command.go — check the file for exact spellings.

Inspect status

go run cmd/main.go --migrate:status

Use this when CI complains or when you suspect partial application.

Roll back

Rollback one batch (optional batch count):

go run cmd/main.go --migrate:rollback 1

Rollback everything tracked (dangerous in production — use only in dev or with backups):

go run cmd/main.go --migrate:rollback:all

Scaffold a new migration

go run cmd/main.go --migrate:create:add_user_preferences

Open the generated file, implement Up / Down (or the interfaces your manager expects), then register it in database/migration.go if the generator does not do so automatically.

Entities and migrations — stay aligned

When you add a column:

  1. Migration adds/alters the column at the database level.
  2. Entity struct gains the field with correct GORM tags.
  3. DTOs expose the field to HTTP where appropriate.
  4. Repositories read/write the new field.

Skipping step 1 causes runtime errors; skipping step 2 causes silent omission of data in ORM operations.

PostgreSQL extensions

The starter may attempt to ensure uuid-ossp (see RunExtension in database config). On managed databases you might need elevated privileges or a provider-specific UUID type — adjust for your host’s rules.

Seeding

go run cmd/main.go --seed

Seeding is not automatically idempotent unless you wrote it that way (ON CONFLICT, FirstOrCreate, etc.). Treat production seed with extreme care — prefer dedicated admin tools or one-off jobs.

Backup and restore (operations)

This template does not automate backups. For real systems:

  • Schedule logical dumps (pg_dump) or disk snapshots.
  • Test restore quarterly.

Document your organisation’s RPO/RTO targets separately.

Troubleshooting

SymptomLikely cause
relation does not existMigration not applied on that database.
column X does not existCode ahead of migrations or wrong DB targeted.
Rollback errorsDown migration missing or not inverse of Up.

Capture --migrate:status output when asking for help — it tells readers which version the database believes it is on.