PocketBase provides a simple migrate
command, allowing you to share your DB structure, create
collections programmatically, initialize default settings and/or run anything that needs to be executed only
once.
The migrate
command comes also with "automigrate" functionality that will create seamlessly the
necessary migration files for you when making collection changes from the Admin UI.
You can write migrations with Go or JavaScript (more information will be available soon).
Enable Go migrations
The prebuilt executable enables the migrate
command by default, but when you are extending PocketBase
with Go you have to enable it manually:
// main.go
package main
import (
"log"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/plugins/migratecmd"
// uncomment once you have at least one .go migration file in the "migrations" directory
// _ "yourpackage/migrations"
)
func main() {
app := pocketbase.New()
migratecmd.MustRegister(app, app.RootCmd, &migratecmd.Options{
Automigrate: true, // auto creates migration files when making collection changes
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
migrate create
The easiest way to create a new migration file is to use migrate create
during development:
// Since the "create" command makes sense only during development,
// it is expected the user to be in the app working directory
// and to be using "go run ..."
[root@dev project]$ go run main.go migrate create "your_new_migration"
The above will create a new directory migrations
with a blank migration file inside it.
To make your application aware of the registered migrations, you simply have to import the above
migrations
package in one of your main
package files:
package main
import _ "yourpackage/migrations"
// ...
Here is for example what a single migration file could look like:
// migrations/1655834400_your_new_migration.go
package migrations
import (
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/daos"
m "github.com/pocketbase/pocketbase/migrations"
)
func init() {
m.Register(func(db dbx.Builder) error {
// set a default "pending" status to all articles
query := db.NewQuery("UPDATE articles SET status = 'pending' WHERE status = ''")
if _, err := query.Execute(); err != nil {
return err
}
// you can also access the Dao helpers
dao := daos.New(db)
record, _ := dao.FindRecordById("articles", "RECORD_ID")
record.Set("status", "active")
if err := dao.SaveRecord(record); err != nil {
return err
}
// and even set default app settings
settings, _ := dao.FindSettings()
settings.Meta.AppName = "test"
settings.Smtp.Enabled = false
if err := dao.SaveSettings(settings); err != nil {
return err
}
return nil
}, func(db dbx.Builder) error {
// revert changes...
return nil
})
}
And as a bonus, being
.go
files also ensures that the migrations will be embedded seamlessly
in your final executable.
When you deploy the final executable on your production server, the new migrations will be auto applied with the start of the application.
Optionally, you could apply new migrations explicitly using migrate up
:
[root@dev ~]$ ./yourapp migrate up
To revert the last applied migration(s), you could run migrate down [number]
:
[root@dev ~]$ ./yourapp migrate down
migrate collections
PocketBase comes also with a migrate collections
command that will generate a full snapshot of
your current Collections configuration without having to type it manually:
// Since the "collections" command makes sense only during development,
// it is expected the user to be in the app working directory
// and to be using "go run ..."
[root@dev project]$ go run main.go migrate collections
Similar to the migrate create
command, this will generate a new migration file in the
migrations
directory.
It is safe to run the command multiple times and generate multiple migration files.
If Automigrate
is enabled, running this command usually is not necessarily since every
collection change will have its own migration file.