Install the Atlas SDK for Go
masterTo use the Atlas SDK for building providers in Go, install the package using go get.
go get -u ariga.io/atlas@masterrepository·master·Indexed 27 days ago
https://github.com/ariga/atlasAtlas is a language-agnostic tool for managing and migrating database schemas using declarative and versioned workflows. It provides capabilities for schema inspection, diffing, linting, and testing, and supports 16 ORMs across Go, TypeScript, Python, Java, .NET, and PHP. The tool includes an SDK for Go and an API client for Atlas Cloud.
To use the Atlas SDK for building providers in Go, install the package using go get.
go get -u ariga.io/atlas@masterAtlas includes over 50 built-in analyzers to catch destructive changes (like dropped columns), data-dependent modifications, and database-specific risks like table locks. Use the atlas migrate lint command to review migration files. A --dev-url is required for validation.
atlas migrate lint --dev-url "docker://postgres/16/dev"The integration tests require database containers managed via Docker Compose. Use the provided docker-compose.yaml to start the necessary database images for the test suite.
docker-compose --project-name atlas-integration up -dTo save resources, you can run specific tests or subsets of tests using the -run and -dialect flags. This allows you to run tests without having all database containers active, provided the specific containers required by the selected tests are running.
Use the -run flag with the test name. To target a specific subtest (e.g., a specific database version), use the slash / syntax.
Use the -dialect flag to filter tests by a specific database version/dialect.
Examples:
TestMySQL_Executor for all MySQL versions: -run='MySQL_Executor'TestMySQL_Executor for MySQL 5.6 only: -run='MySQL_Executor/mysql56'TestPostgres_Executor for Postgres 10 only: -run='Postgres_Executor/postgres10'TiDB tests for version tidb5: -run='TiDB' -dialect='tidb5'# Run TestMySQL_Executor for all mysql versions
go test -run='MySQL_Executor' ./...
# Run TestMySQL_Executor for mysql 5.6 only
go test -run='MySQL_Executor/mysql56' ./...
# Run TestPostgres_Executor for postgres 10 only
go test -run='Postgres_Executor/postgres10' ./...
# Run all tests for one specific dialect, like only TiDB 5
go test -run='TiDB' -dialect='tidb5' ./...You can unit test database logic (functions, views, triggers, procedures) and data migrations using .test.hcl files. Use the atlas schema test command with a --dev-url to execute these tests.
test "schema" "postal" {
# Valid postal codes pass
exec {
sql = "SELECT '12345'::us_postal_code"
}
# Invalid postal codes fail
catch {
sql = "SELECT 'hello'::us_postal_code"
}
}
test "schema" "seed" {
for_each = [
{input: "hello", expected: "HELLO"},
{input: "world", expected: "WORLD"},
]
exec {
sql = "SELECT upper('${each.value.input}')"
output = each.value.expected
}
}atlas schema test --dev-url "docker://postgres/16/dev"You can install Atlas using several methods depending on your platform:
ariga/tap/atlas tap.arigaio/atlas image.npx @ariga/atlas.To execute the complete suite of integration tests, run the Go test command from within the internal/integration directory. Note that this requires all database containers defined in the docker-compose.yaml to be running.
go test ./...To regenerate the SQLite parser code, you must have antlr4 installed on your system. The process involves running the ANTLR4 tool with the Go language target, specifying the sqliteparse package, and using the visitor pattern for the Lexer.g4 and Parser.g4 grammar files. After generation, the temporary files _lexer.go and _parser.go must be renamed to lexer.go and parser.go respectively, and intermediate files should be cleaned up.
antlr4 -Dlanguage=Go -package sqliteparse -visitor Lexer.g4 Parser.g4 \
&& mv _lexer.go lexer.go \
&& mv _parser.go parser.go \
&& rm *.interp *.tokensrelease.json.You can skip specific linting diagnostics or entire files using nolint directives within your SQL migration files.
atlas:nolint to the file.atlas:nolint <CODE> (e.g., atlas:nolint DS101).atlas:nolint <AnalyzerName> to skip all diagnostics from a specific analyzer.The atlas schema inspect command connects to a database and prints its schema in Atlas DDL syntax. This is useful for generating .hcl files from existing databases.
Usage Examples:
# Inspect a specific database and save to a file
atlas schema inspect -u "mysql://user:pass@localhost:3306/dbname" > schema.hcl
# Inspect multiple specific schemas
atlas schema inspect -u "mariadb://user:pass@localhost:3306/" --schema=schemaA,schemaB -s schemaC
# Inspect a SQLite database
atlas schema inspect -u "sqlite://file:ex1.db?_fk=1"Flags:
-u, --url: (Required) The URL of the resource to inspect (e.g., mysql://user:pass@host:port/dbname).--dev-url: The URL of a dev database.-s, --schema: Set specific schema names to include.--exclude: List of glob patterns used to filter resources.--format / --log: Go template to use to format the output.atlas schema inspect -u "mysql://user:pass@localhost:3306/dbname" > schema.hcl
atlas schema inspect -u "mariadb://user:pass@localhost:3306/" --schema=schemaA,schemaB -s schemaC
atlas schema inspect --url "postgres://user:pass@host:port/dbname?sslmode=disable"
atlas schema inspect -u "sqlite://file:ex1.db?_fk=1"Atlas allows you to define roles, permissions, and row-level security policies using HCL. This enables managing database access control as version-controlled code.
role "app_readonly" {
comment = "Read-only access for reporting"
}
role "app_writer" {
comment = "Read-write access for the application"
member_of = [role.app_readonly]
}
user "api_user" {
password = var.api_password
conn_limit = 20
comment = "Application API service account"
member_of = [role.app_writer]
}
permission {
for_each = [table.orders, table.products, table.users]
for = each.value
to = role.app_readonly
privileges = [SELECT]
}
policy "tenant_isolation" {
on = table.orders
for = ALL
to = ["app_writer"]
using = "(tenant_id = current_setting('app.current_tenant')::integer)"
check = "(tenant_id = current_setting('app.current_tenant')::integer)"
}