Initial commit

This commit is contained in:
2026-04-17 23:26:01 +00:00
commit 2ea4ca5d52
409 changed files with 63459 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
---
title: Version Your Schema with Go Migrations
impact: HIGH
impactDescription: Guarantees repeatable, transactional schema evolution and eliminates manual dashboard changes in production
tags: go, migrations, schema, database, migratecmd, extending
---
## Version Your Schema with Go Migrations
PocketBase ships with a `migratecmd` plugin that generates versioned `.go` migration files, applies them automatically on `serve`, and lets you roll back with `migrate down`. Because the files are compiled into your binary, no extra migration tool is needed.
**Incorrect (one-off SQL or dashboard changes in production):**
```go
// ❌ Running raw SQL directly at startup without a migration file
// the change is applied every restart and has no rollback path.
app.OnServe().BindFunc(func(se *core.ServeEvent) error {
_, err := app.DB().NewQuery(
"ALTER TABLE posts ADD COLUMN summary TEXT DEFAULT ''",
).Execute()
return err
})
// ❌ Forgetting to import the migrations package means
// registered migrations are never executed.
package main
import (
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
// _ "myapp/migrations" ← omitted: migrations never run
)
```
**Correct (register migratecmd, import migrations package):**
```go
// main.go
package main
import (
"log"
"os"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
"github.com/pocketbase/pocketbase/tools/osutils"
// Import side-effects only; this registers all init() migrations.
_ "myapp/migrations"
)
func main() {
app := pocketbase.New()
migratecmd.MustRegister(app, app.RootCmd, migratecmd.Config{
// Automigrate generates a new .go file whenever you make
// collection changes in the Dashboard (dev-only).
Automigrate: osutils.IsProbablyGoRun(),
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
```
**Create and write a migration:**
```bash
# Create a blank migration file in ./migrations/
go run . migrate create "add_summary_to_posts"
```
```go
// migrations/1687801090_add_summary_to_posts.go
package migrations
import (
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(app core.App) error {
// app is a transactional App instance safe to use directly.
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
return err
}
collection.Fields.Add(&core.TextField{
Name: "summary",
Required: false,
})
return app.Save(collection)
}, func(app core.App) error {
// Optional rollback
collection, err := app.FindCollectionByNameOrId("posts")
if err != nil {
return err
}
collection.Fields.RemoveByName("summary")
return app.Save(collection)
})
}
```
**Snapshot all collections (useful for a fresh repo):**
```bash
# Generates a migration file that recreates your current schema from scratch.
go run . migrate collections
```
**Clean up dev migration history:**
```bash
# Remove _migrations table entries that have no matching .go file.
# Run after squashing or deleting intermediate dev migration files.
go run . migrate history-sync
```
**Apply / roll back manually:**
```bash
go run . migrate up # apply all unapplied migrations
go run . migrate down 1 # revert the last applied migration
```
**Key details:**
- Migration functions receive a **transactional** `core.App` treat it as the database source of truth. Never use the outer `app` variable inside migration callbacks.
- New unapplied migrations run automatically on every `serve` start no manual step in production.
- `Automigrate: osutils.IsProbablyGoRun()` limits auto-generation to `go run` (development) and prevents accidental file creation in production binaries.
- Prefer the collection API (`app.Save(collection)`) over raw SQL `ALTER TABLE` so PocketBase's internal schema cache stays consistent.
- Commit all generated `.go` files to version control; do **not** commit `pb_data/`.
Reference: [Extend with Go Migrations](https://pocketbase.io/docs/go-migrations/)