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 ¶
- Variables
- func AppliedMigrations(ctx context.Context, sqlDB *sql.DB) (map[MigrationKey]bool, error)
- func ApplyPending(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, migrations []Migration) error
- func ApplyStep(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, step Step) error
- func EnsureTrackingTable(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect) error
- func IsMissingTrackingTable(err error) bool
- func RollbackLast(ctx context.Context, sqlDB *sql.DB, dialect db.Dialect, migrations []Migration) error
- type AddColumn
- type AlterColumnType
- type AlterColumnUnique
- type Column
- type ColumnState
- type CreateIndex
- type CreateTable
- type DropColumn
- type DropIndex
- type DropTable
- type Migration
- type MigrationKey
- type Model
- type Rename
- type RenameColumn
- type RenameTable
- type SchemaState
- type Step
- type TableState
Constants ¶
This section is empty.
Variables ¶
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.
var ErrIrreversibleMigration = errors.New("tango migration: migration is irreversible")
ErrIrreversibleMigration is returned by RollbackLast when the most recently applied migration is marked irreversible.
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.
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 ¶
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 ¶
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 ¶
EnsureTrackingTable creates the tango_migrations table if it doesn't already exist.
func IsMissingTrackingTable ¶
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 ¶
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 ¶
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 ¶
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 ¶
CreateTable creates a table with the provided columns. It is exported for generated migration files; application code should use the tango CLI.
type DropColumn ¶
DropColumn removes a column from an existing table. It is exported for generated migration files; application code should use the tango CLI.
type DropIndex ¶
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 ¶
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 ¶
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 ¶
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
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
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
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.