File: input.md

package info (click to toggle)
golang-ariga-atlas 0.7.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 5,676 kB
  • sloc: javascript: 592; sql: 404; makefile: 10
file content (97 lines) | stat: -rw-r--r-- 2,501 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
---
id: input-variables
slug: /atlas-schema/input-variables
title: Input Variables
---
In some cases, it is desirable to reuse an Atlas HCL document in different contexts.
For example, many organizations manage a multi-tenant architecture where the same database
schema is replicated per tenant. For this reason, the Atlas DDL supports input variables.

Input variables are defined using the `variable` block:

```hcl
variable "comment" {
  type = string // | int | bool
  default = "rotemtam"
}
```

Once defined, their value can be referenced using `var.<name>`:

```hcl
schema "main" {
  comment = var.comment
}
```

Finally, input variables are passed to Atlas in the `schema apply` command using the
`--var` flag:

```shell
atlas schema apply -u ... -f atlas.hcl --var comment="hello"
```

If a variable is not set from the command line, Atlas tries to use its default value.
If no default value is set, an error is returned:

```text
schemahcl: failed decoding: input value "tenant" expected but missing
```

### Variable schema names

Returning to the use case we described above, let's see how we can use input variables
to manage a multi-tenant architecture.

First, we define our schema in a file named `multi.hcl`:

```hcl title="multi.hcl"
// Define the input variable that contains the tenant name.
variable "tenant" {
	type = string
}

// Define the schema, "tenant" here is a placeholder for the final
// schema name that will be defined at runtime.
schema "tenant" {
    // Reference to the input variable.
	name = var.tenant
}
table "users" {
    // Refer to the "tenant" schema. It's actual name will be
    // defined at runtime.
	schema = schema.tenant
	column "id" {
		type = int
	}
}
```

Now suppose we have two tenants, `jerry` and `george`. We can apply the same schema twice:

Once for Jerry:
```text
atlas schema apply -u mysql://user:pass@localhost:3306/ --schema jerry --var tenant=jerry
```
Observe the generated queries apply to the `jerry` schema:
```text
-- Planned Changes:
-- Add new schema named "jerry"
CREATE DATABASE `jerry`
-- Create "users" table
CREATE TABLE `jerry`.`users` (`id` int NOT NULL)
✔ Apply
```
And again for George:
```text
atlas schema apply -u mysql://user:pass@localhost:3306/ --schema george --var tenant=george
```
The generated queries create the `george` schema:
```text
-- Planned Changes:
-- Add new schema named "george"
CREATE DATABASE `george`
-- Create "users" table
CREATE TABLE `george`.`users` (`id` int NOT NULL)
✔ Apply
```