Skip to main content
Version: 1.1.0

Migrations API Reference

Reference for schema creation, schema sync, indexes, foreign keys, and versioned migrations.

Client Schema Helpers​

Migrate(ctx context.Context, models ...any) error​

Creates missing tables for the given models.

err := client.Migrate(ctx, &User{}, &Order{}, &Product{})

Migrate also creates many-to-many join tables for relations tagged rel:"many_to_many" with an m2m tag.

Sync(ctx context.Context, opts SyncOptions, models ...any) error​

Synchronizes existing tables with model metadata.

err := client.Sync(ctx, quark.SyncOptions{}, &User{})

Supported sync operations:

ChangeSupport
Missing tableCalls Migrate unless DryRun is true.
New columnAdds the column.
Renamed columnUses quark:"rename:old_col".
Removed columnDrops only when SafeMigrations is false.
type SyncOptions struct {
DryRun bool
NoTransaction bool
}

CreateIndex(ctx, table, indexName string, columns []string, unique bool) error​

Creates a simple index.

err := client.CreateIndex(
ctx,
"users",
"idx_users_email",
[]string{"email"},
true,
)

AddForeignKey(ctx, table, constraintName string, columns []string, refTable string, refColumns []string, onDelete, onUpdate string) error​

Adds a foreign key constraint.

err := client.AddForeignKey(
ctx,
"orders",
"fk_orders_user",
[]string{"user_id"},
"users",
[]string{"id"},
"CASCADE",
"",
)

Versioned Migrations​

migrate.Register(m *Migration)​

Registers a migration in the global migration registry.

migrate.Register(&migrate.Migration{
ID: "202605050001_add_email_index",
Name: "add email index",
Up: func(ctx context.Context, client *quark.Client) error {
return client.CreateIndex(ctx, "users", "idx_users_email", []string{"email"}, true)
},
Down: func(ctx context.Context, client *quark.Client) error {
return client.Exec(ctx, "DROP INDEX idx_users_email")
},
})

Migration IDs are sorted lexicographically. Use timestamp-like IDs.

type Migration struct {
ID string
Name string
Message string
Up func(ctx context.Context, client *quark.Client) error
Down func(ctx context.Context, client *quark.Client) error
}

migrate.Reset()​

Clears the migration registry. Intended for tests.

Migrator​

migrate.NewMigrator(client *quark.Client) *Migrator​

Creates a migrator bound to a client.

migrator := migrate.NewMigrator(client)

The migrator stores applied migration IDs in quark_migrations.

Init(ctx context.Context) error​

Creates the migration tracking table if needed.

err := migrator.Init(ctx)

Up(ctx context.Context, steps int) error​

Applies pending migrations in ID order.

err := migrator.Up(ctx, 0) // apply all pending
err = migrator.Up(ctx, 2) // apply at most two

UpDryRun(ctx context.Context, steps int) error​

Prints pending migrations without executing their Up functions.

err := migrator.UpDryRun(ctx, 0)

Down(ctx context.Context, steps int) error​

Reverts applied migrations in reverse ID order.

err := migrator.Down(ctx, 1)

Raw SQL Requirement​

migrate.Migrator uses client.Exec for its tracking table changes. Configure the migration client with AllowRawQueries: true:

limits := quark.DefaultLimits()
limits.AllowRawQueries = true

client, err := quark.New("postgres", dsn,
quark.WithLimits(limits),
)

High-level helpers such as Migrate, Sync, CreateIndex, and AddForeignKey do not require AllowRawQueries.