migrate

package
v0.1.29 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

README

HCL migrations

migrate.Apply reconciles PostgreSQL tables with Atlas HCL and runs colocated SQL migrations. Every bundle should use a stable WithName when more than one bundle can share a database.

Schema-scoped bundles

WithSchema applies one bundle inside a normalized PostgreSQL schema and leaves the default behavior on public unchanged:

err := migrate.Apply(ctx, dsn, schemaFS,
    migrate.WithName("runtime"),
    migrate.WithSchema("agent_tenant_context"),
)

The schema name must be a lowercase PostgreSQL identifier no longer than 63 bytes. The migration creates the schema, scopes Atlas inspection and HCL objects, SQL migration metadata, dependent-view handling, and managed security to it. A reusable HCL bundle must declare only schema "public" {}; the migration remaps that declaration to the selected schema.

SQL files run with the selected schema as search_path. Keep objects owned by the bundle unqualified in SQL files so the same bundle can target different schemas. Explicitly qualified SQL remains explicit and is not rewritten.

Reusable test database templates

migrate.NewProvisioner adapts the same HCL and SQL bundle to dbtest.Options.Provisioner:

handle := dbtest.ForT(t, dbtest.Options{
    Name:    "query_sessions",
    LogName: "query-sessions-test",
    Provisioner: migrate.NewProvisioner(
        querySchema,
        migrate.WithDir("migrations"),
        migrate.WithName("query"),
    ),
})

The provisioner fingerprints the migration name, directory, Atlas options, variables, and every HCL and SQL file. dbtest prepares one sealed PostgreSQL template for that fingerprint, clones an isolated database for each call, and keeps the template for later tests. Normal hash-gated SQL is already present in the clone; runs: always scripts and security reconciliation still run for every instance.

This option requires database creation. dbtest fails before invoking the provisioner when COMMONS_DB_CREATE=false because that mode targets the configured database directly.

SQL files default to the post-Atlas phase. Directives are read from the leading comment header:

-- phase: pre
-- dependsOn: 001_extensions.sql
-- runs: always
-- transaction: false
  • phase is pre or post; omitted means post.
  • dependsOn uses paths relative to the migration root. Dependencies are topologically ordered and changes rerun all transitive dependents.
  • scripts are transactional by default; the SQL and its SHA-256 migration log commit atomically.
  • runs: always re-runs a script on every apply, including a plain process boot against an unchanged database. It is an escape hatch, not the norm. Normal scripts are hash-gated: they run once and re-run only when their content changes. Views are restored automatically when Atlas reshapes a base table they depend on — migrate.Apply drops the dependent view and re-runs the script that creates it — so a view file never needs runs: always to stay current. Reserving always for the rare script that must reconcile on every apply keeps steady-state boots DDL-free; a bundle full of always scripts re-issues ACCESS EXCLUSIVE-locking DDL on every connection and will deadlock live readers. Prefer splitting DDL into small hash-gated files — one file per view (or per shared dependency), triggers and constraints in their own run-once files — so a table reshape only re-creates the views that actually depend on it and never disturbs unrelated triggers or constraints.

Atlas-style PostgreSQL role and permission blocks may live in the same HCL files as tables. The OSS migration layer supports roles and memberships plus schema, table, column, and sequence permissions. Managed grants are reconciled exactly within the bundle's metadata scope; unrelated roles and grants are left untouched. Different scopes must not manage the same role or grantee/object pair.

Documentation

Overview

Package migrate applies declarative Atlas HCL schemas to PostgreSQL databases.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Apply

func Apply(ctx context.Context, connection string, schemaFS fs.FS, opts ...Option) error

Apply loads colocated HCL and SQL migrations from schemaFS. SQL scripts marked phase pre run before the Atlas realm diff; all other SQL defaults to the post phase. Declared PostgreSQL roles and permissions are reconciled last. Tables absent from a partial schema bundle are never dropped unless WithTableDrops is supplied.

func ConnectionForSchema added in v0.1.28

func ConnectionForSchema(connection, schemaName string) (string, error)

ConnectionForSchema returns a PostgreSQL URL whose connections select schemaName.

func ValidateSchemaName added in v0.1.28

func ValidateSchemaName(name string) error

ValidateSchemaName validates an application-normalized PostgreSQL schema identifier.

Types

type Option

type Option func(*options)

Option configures an HCL migration.

func WithDir

func WithDir(dir string) Option

WithDir selects the root containing colocated HCL and SQL migrations.

func WithExclude

func WithExclude(patterns ...string) Option

WithExclude excludes database objects from Atlas inspection. Values use Atlas's schema inspection patterns (for example "table.column").

func WithName

func WithName(name string) Option

WithName sets the metadata scope used for SQL hashes and managed security. It should be stable and unique for each migration bundle sharing a database.

func WithSchema added in v0.1.28

func WithSchema(name string) Option

WithSchema selects the PostgreSQL schema used for the complete migration lifecycle.

func WithTableDrops

func WithTableDrops() Option

WithTableDrops allows HCL files to remove tables. Drops are suppressed by default so a partial schema bundle cannot delete tables owned by consumers.

func WithVariables

func WithVariables(input map[string]cty.Value) Option

WithVariables supplies values for HCL variable blocks and security expressions.

type SchemaProvisioner added in v0.1.26

type SchemaProvisioner struct {
	// contains filtered or unexported fields
}

SchemaProvisioner prepares reusable dbtest templates and reconciles each cloned database using the same migration behavior as Apply.

func NewProvisioner added in v0.1.26

func NewProvisioner(schemaFS fs.FS, opts ...Option) *SchemaProvisioner

NewProvisioner adapts an HCL migration bundle to dbtest.Provisioner without coupling the migrate package to dbtest. Options are frozen at construction.

func (*SchemaProvisioner) Fingerprint added in v0.1.26

func (p *SchemaProvisioner) Fingerprint(ctx context.Context) (string, error)

Fingerprint returns a deterministic identity for all inputs that affect the database produced by this provisioner.

func (*SchemaProvisioner) PrepareInstance added in v0.1.26

func (p *SchemaProvisioner) PrepareInstance(ctx context.Context, connection string) error

PrepareInstance reconciles instance-specific and always-run migrations after cloning a prepared template.

func (*SchemaProvisioner) PrepareTemplate added in v0.1.26

func (p *SchemaProvisioner) PrepareTemplate(ctx context.Context, connection string) error

PrepareTemplate applies the full migration bundle to a new template.

Directories

Path Synopsis
Package viewdeps finds, drops, and restores the views and materialized views that transitively depend on a set of tables, so DDL PostgreSQL refuses while a dependent view exists — DROP TABLE, DROP COLUMN, ALTER COLUMN TYPE — can proceed.
Package viewdeps finds, drops, and restores the views and materialized views that transitively depend on a set of tables, so DDL PostgreSQL refuses while a dependent view exists — DROP TABLE, DROP COLUMN, ALTER COLUMN TYPE — can proceed.

Jump to

Keyboard shortcuts

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