Last active
July 30, 2024 20:06
-
-
Save ks2211/816d531bff8935eb40dddbcc42a2b0e7 to your computer and use it in GitHub Desktop.
Using atlasexec (go SDK) to run migrations for multi tenants
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
variable "url" { | |
type = string | |
} | |
data "hcl_schema" "schema" { | |
path = "schema.hcl" | |
} | |
env { | |
name = atlas.env | |
url = var.url | |
src = data.hcl_schema.schema.url | |
diff { | |
skip { | |
drop_schema = true | |
drop_table = true | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"embed" | |
"fmt" | |
"strings" | |
"log" | |
"ariga.io/atlas-go-sdk/atlasexec" | |
) | |
//go:embed schema.hcl | |
//go:embed atlas.hcl | |
var embedFS embed.FS | |
const ( | |
atlasSchemaFile = "atlas.hcl" | |
schemaFileName = "schema.hcl" | |
) | |
func main() { | |
ctx := context.Background() | |
var dryRun bool // flag/env var | |
var dbURL string // flag/env var | |
var tenantIDs []string // fetch this from another source (e.g a file, another db, api, etc) | |
// create the atlas.hcl file | |
atlasSchema, err := embedFS.ReadFile(atlasSchemaFile) | |
if err != nil { | |
panic(err) | |
} | |
// Define the execution context, supplying a migration directory | |
// and potentially an `atlas.hcl` configuration file using `atlasexec.WithHCL`. | |
workdir, err := atlasexec.NewWorkingDir( | |
atlasexec.WithAtlasHCLString(string(atlasSchema)), | |
) | |
if err != nil { | |
panic(err) | |
} | |
// atlasexec works on a temporary directory, so we need to close it | |
defer workdir.Close() | |
// embed the migrations schema file | |
schemaFile, err := embedFS.ReadFile(schemaFileName) | |
if err != nil { | |
panic(err) | |
} | |
schemaFilePath, err := workdir.WriteFile(redshiftSchemaFile, schemaFileDat) | |
if err != nil { | |
panic(err) | |
} | |
client, err := atlasexec.NewClient(workdir.Path(), "atlas") | |
if err != nil { | |
panic(err) | |
} | |
// loop | |
for i := range tenantIDs { | |
// need to exclude the current tenant from the excludes so the migration runs on it | |
// also exclude public to avoid working against public schema | |
var excludes []string | |
excludes = append(excludes, companyIDs[:i]...) | |
excludes = append(excludes, companyIDs[i+1:]...) | |
excludes = append(excludes, "public") | |
resp, err := client.SchemaApply(ctx, &atlasexec.SchemaApplyParams{ | |
URL: dbURL, | |
DryRun: dryRun, | |
Exclude: excludes, | |
Vars: atlasexec.Vars{ | |
"tenant": tenantIDs[i], | |
"url": dbURL, | |
}, | |
To: fmt.Sprintf("file://%s", schemaFilePath), | |
}) | |
if err != nil { | |
log.Error("error doing migraton for tenant %v, error %v", tenantIDs[i], err) | |
continue | |
} | |
log.Debug("migrations for tenant %v response pending %v, applied %v", tenantIDs[i], strings.Join(resp.Changes.Pending, "\n"), strings.Join(resp.Changes.Applied, "\n")) | |
log.Info("completed migration for tenant %v", tenantIDs[i]) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// schema.hcl | |
variable "tenant" { | |
type = string | |
description = "The schema we operate on" | |
} | |
schema "tenant" { | |
name = var.tenant | |
} | |
table "your_table" { | |
schema = schema.tenant | |
column "id" { | |
type = uuid | |
} | |
// other fields | |
primary_key { | |
columns = [column.id] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment