Help us shape the future of Go! Take the 2026 Go Developer Survey

migration

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package migration applies and rolls back the schema migrations `tango makemigrations` generates.

An application hands its Migration values to ApplyPending and RollbackLast, which record what has run in the tango_migrations table; a generated project's main does this through tango.DispatchFlags. EnsureTrackingTable, AppliedMigrations, IsMissingTrackingTable and MigrationKey read that record.

The step types (Step, Column, CreateTable and the other steps), Model, SchemaState and its parts, the diff and replay functions, and ApplyStep exist for generated migration files and the tango CLI. They are not covered by tanGO's compatibility promise and may change in any minor release, with one exception, the Generated-file contract: a migration file written by a released `tango makemigrations` keeps compiling, being read by later runs, applying and rolling back on every later v0.x release. See https://tangoframework.com/docs/compatibility/ and https://tangoframework.com/docs/guides/migrations/.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidRename = errors.New("tango migration: invalid rename")

ErrInvalidRename is returned by DiffModels when a Rename mapping does not describe a column history has and the models have under a new name.

View Source
var ErrIrreversibleMigration = errors.New("tango migration: migration is irreversible")

ErrIrreversibleMigration is returned by RollbackLast when the most recently applied migration is marked irreversible.

View Source
var ErrNoAppliedMigrations = errors.New("tango migration: no applied migrations to roll back")

ErrNoAppliedMigrations is returned by RollbackLast when tango_migrations has nothing recorded to roll back.

View Source
var ErrUnsupportedChange = errors.New("tango migration: a model change cannot be expressed as a migration")

ErrUnsupportedChange is returned by Diff when the models changed in a way no migration step can express: a type change that is not a Widening type change (or one to a primary key, or whose default cannot convert), a change to which column is the primary key, or a foreign key gained, lost or retargeted on an existing column. Generating nothing would leave the database silently out of step with the models, so Diff refuses.

Functions

func AppliedMigrations

func AppliedMigrations(ctx context.Context, sqlDB *sql.DB) (map[MigrationKey]bool, error)

AppliedMigrations returns the set of applied app-scoped migration keys.

func ApplyPending

func ApplyPending(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, migrations []Migration) error

ApplyPending applies every migration in migrations whose (App, Name) is not already recorded in tango_migrations, translating each Up step via ApplyStep and recording one tango_migrations row per (app, name) pair the migration touches. Slice order does not matter: pending migrations run by Name then App, except that a migration adding a foreign key to another app's table runs after the migration creating that table, so cross-app foreign keys work regardless of app names or InstalledApps order. Each app's own migrations always run in Name order. Foreign keys between apps that form a cycle are an error, and nothing is applied.

func ApplyStep

func ApplyStep(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, step Step) error

ApplyStep executes step against sqlDB, translating it into the DDL appropriate for dialect. A SQLite step it cannot express as a direct ALTER TABLE (DropColumn, AlterColumnType) is applied by rebuilding the table, keeping everything else about it (see rebuildSQLiteTable). It is exported so ApplyPending and the tango CLI can share DDL translation; application code should use tango migrate rather than calling ApplyStep directly.

func EnsureTrackingTable

func EnsureTrackingTable(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect) error

EnsureTrackingTable creates the tango_migrations table if it doesn't already exist.

func IsMissingTrackingTable

func IsMissingTrackingTable(err error) bool

IsMissingTrackingTable reports whether err means the tango_migrations table does not exist yet. Status uses this to stay read-only: creating the tracking table remains ApplyPending's responsibility.

func RollbackLast

func RollbackLast(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, migrations []Migration) error

RollbackLast rolls back the most recently applied migration (by applied_at; among migrations applied at the same instant, the last one in ApplyPending's order) by running its Down steps, then removes its tango_migrations row(s). It fails, changing nothing, if that migration is marked irreversible in migrations, or if migrations doesn't contain it.

Types

type AddColumn

type AddColumn struct {
	Table  string
	Column Column
}

AddColumn adds a column to an existing table. It is exported for generated migration files; application code should use the tango CLI.

type AlterColumnType added in v0.1.0

type AlterColumnType struct {
	Table  string
	Column string
	From   string
	// FromLength and ToLength are the varchar lengths of From and To, and 0
	// for any other type. They are additive: files written without them
	// mean what they always meant.
	FromLength int `json:",omitempty"`
	To         string
	ToLength   int `json:",omitempty"`
	Default    string
}

AlterColumnType changes a column's type by a Widening type change, converting every row's value with explicit SQL for the dialect. Default, when set, is the column's existing default converted to the new type (a raw SQL literal); the column keeps NOT NULL. A migration containing it is irreversible. It is exported for generated migration files; application code should use the tango CLI.

type AlterColumnUnique

type AlterColumnUnique struct {
	Table  string
	Column string
	Unique bool
}

AlterColumnUnique changes a column's uniqueness constraint. It is exported for generated migration files; application code should use the tango CLI.

type Column

type Column struct {
	Name string
	Type string
	// Length is the maximum number of characters of a "varchar" column, and
	// 0 for every other type. It is an additive field: generated files
	// written before it existed leave it 0 and mean what they always meant.
	Length     int `json:",omitempty"`
	PrimaryKey bool
	Unique     bool
	Indexed    bool
	// References is the target table name for a foreign key column (from a
	// tango:"fk=X" tag), or "" for an ordinary column. The generated
	// constraint is always RESTRICT/NO ACTION: cascade delete is
	// implemented in application code by Store.Delete, never by the
	// database itself.
	References string
	// Default is a raw SQL literal (e.g. "TRUE") the column is given as a
	// NOT NULL DEFAULT when adding it to an existing table, so pre-existing
	// rows backfill to that value instead of NULL. Empty means no default:
	// the column is added exactly as before this field existed. There is no
	// struct-tag-driven way to set this — it is only ever hand-authored on a
	// specific generated migration where an existing model needs it.
	Default string
}

Column describes the SQL-relevant shape of one table column. It is exported for generated migration files and CLI diffing, not as a hand-authored application API.

type ColumnState

type ColumnState struct {
	Name       string
	Type       string
	Length     int
	PrimaryKey bool
	Unique     bool
	Indexed    bool
	References string
	// Default is the column's database default as a raw SQL literal, set
	// by an AddColumn that carried one and converted by AlterColumnType.
	// CreateTable never writes a default (see columnDefSQL), so replay
	// never takes one from it.
	Default string
}

ColumnState is a column's shape as reconstructed by Replay. It is exported only for the tango CLI's migration replay/diff machinery.

type CreateIndex

type CreateIndex struct {
	Table  string
	Column string
}

CreateIndex creates a plain index for a table column. It is exported for generated migration files; application code should use the tango CLI.

type CreateTable

type CreateTable struct {
	Table   string
	Columns []Column
}

CreateTable creates a table with the provided columns. It is exported for generated migration files; application code should use the tango CLI.

type DropColumn

type DropColumn struct {
	Table  string
	Column string
}

DropColumn removes a column from an existing table. It is exported for generated migration files; application code should use the tango CLI.

type DropIndex

type DropIndex struct {
	Table  string
	Column string
}

DropIndex removes a plain index for a table column. It is exported for generated migration files; application code should use the tango CLI.

type DropTable

type DropTable struct {
	Table string
}

DropTable removes a table. It is exported for generated migration files; application code should use the tango CLI.

type Migration

type Migration struct {
	App        string
	Name       string
	Up         []Step
	Down       []Step
	Reversible bool
}

Migration groups the up/down steps for one generated migration file. It is part of the runtime contract accepted by ApplyPending and RollbackLast, but application code should normally use values generated by tango makemigrations.

func Diff

func Diff(models []model.ModelMeta, state SchemaState) ([]Migration, error)

Diff compares the desired schema (derived from models) against state (the replayed result of existing migrations) and returns one Migration per app with detected changes, keyed by ModelMeta.App. A model whose App is empty is grouped under the empty-string key. Returns no migrations if nothing changed. A change no step can express fails with ErrUnsupportedChange, naming every such field, and returns no migrations. It is exported only for the tango CLI's makemigrations machinery.

func DiffModels

func DiffModels(models []Model, state SchemaState, renames ...Rename) ([]Migration, error)

DiffModels compares desired model shapes against a replayed migration state, as Diff does. It is exported only for the tango CLI's makemigrations machinery.

type MigrationKey

type MigrationKey struct {
	App  string
	Name string
}

MigrationKey identifies one app-scoped migration row.

type Model

type Model struct {
	App     string
	Name    string
	Columns []Column
	// Struct and Fields are the Go names behind Name and each column's
	// name (column name to Go field name), so makemigrations can name a
	// model or field the way the developer wrote it.
	Struct string
	Fields map[string]string
}

Model is the SQL-relevant model shape makemigrations needs from an app. It is exported so tango's app-side "-tango-dump-models" JSON payload and CLI can share a type; do not treat it as a hand-authored application API.

func ModelsFromMeta

func ModelsFromMeta(models []model.ModelMeta) []Model

ModelsFromMeta converts registered model metadata into the dialect- and reflect-free Model shape the CLI works with (e.g. to serialize as JSON for the "-tango-dump-models" flag convention `tango makemigrations` relies on). It is exported only for tango's CLI/app-side convention.

type Rename added in v0.1.0

type Rename struct {
	App    string
	Table  string
	Column string
	To     string
}

Rename is a Rename mapping. With Column set, the column migration history knows as Table.Column, in App, is the column the models now call To; with Column empty, the table history knows as Table is the model's table the models now call To. Diff turns it into a RenameColumn or RenameTable step instead of a drop and an add, so the data is kept. A field of a renamed model is named by the model's old table name. It is exported for the tango CLI's makemigrations machinery.

type RenameColumn added in v0.1.0

type RenameColumn struct {
	Table string
	From  string
	To    string
}

RenameColumn renames a column, keeping its data, constraints and indexes (an index named after the column takes the new name). It comes from a Rename mapping given to tango makemigrations. It is exported for generated migration files; application code should use the tango CLI.

type RenameTable added in v0.1.0

type RenameTable struct {
	From string
	To   string
}

RenameTable renames a model's table, keeping its rows, constraints and indexes (an index named after the table takes the new name); other tables' foreign keys follow it. It comes from a Rename mapping given to tango makemigrations. It is exported for generated migration files; application code should use the tango CLI.

type SchemaState

type SchemaState struct {
	Tables map[string]TableState
}

SchemaState is the reconstructed shape of every table after replaying a sequence of migrations. It is exported only for the tango CLI's migration replay/diff machinery.

func Replay

func Replay(migrations []Migration) (SchemaState, error)

Replay applies every migration's Up steps, in order, starting from an empty schema, and returns the resulting state. It is exported only for the tango CLI's makemigrations machinery.

type Step

type Step interface {
	// contains filtered or unexported methods
}

Step is a typed, dialect-agnostic schema migration operation. It is exported so generated migration files and the tango CLI can share one representation; do not hand-author Step values directly in application code.

type TableState

type TableState struct {
	Name    string
	App     string
	Columns []ColumnState
}

TableState is a table's shape as reconstructed by Replay. It is exported only for the tango CLI's migration replay/diff machinery.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL