Skip to content

Commit

Permalink
docs and drift test
Browse files Browse the repository at this point in the history
  • Loading branch information
masseelch committed Jun 15, 2022
1 parent 74bebe1 commit 85f1948
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 13 deletions.
24 changes: 18 additions & 6 deletions dialect/sql/schema/migrate_test.go
Expand Up @@ -170,13 +170,16 @@ func TestMigrate_Diff(t *testing.T) {

// Running diff against an existing database without having a types file yet
// will result in the types file respect the "old" order of pk allocations.
for _, stmt := range []string{
"DELETE FROM `ent_types`;",
"INSERT INTO `ent_types` (`type`) VALUES ('groups'), ('users');", // switched allocations
} {
_, err = db.ExecContext(context.Background(), stmt)
require.NoError(t, err)
switchAllocs := func(one, two string) {
for _, stmt := range []string{
"DELETE FROM `ent_types`;",
fmt.Sprintf("INSERT INTO `ent_types` (`type`) VALUES ('%s'), ('%s');", one, two),
} {
_, err = db.ExecContext(context.Background(), stmt)
require.NoError(t, err)
}
}
switchAllocs("groups", "users")
p = t.TempDir()
d, err = migrate.NewLocalDir(p)
require.NoError(t, err)
Expand All @@ -189,6 +192,15 @@ func TestMigrate_Diff(t *testing.T) {
))
requireFileEqual(t, filepath.Join(p, ".ent_types"), atlasDirective+"groups,users")
require.NoFileExists(t, filepath.Join(p, "changes.sql"))

// Drifts in the types file and types database will be detected,
switchAllocs("users", "groups")
require.ErrorContains(t, m.Diff(context.Background()), fmt.Sprintf(
"type allocation range drift detected: %v <> %v: see %s for more information",
[]string{"users", "groups"},
[]string{"groups", "users"},
"https://entgo.io/docs/versioned-migrations#moving-from-auto-migration-to-versioned-migrations",
))
}

func requireFileEqual(t *testing.T, name, contents string) {
Expand Down
7 changes: 7 additions & 0 deletions doc/md/migrate.md
Expand Up @@ -79,6 +79,13 @@ the object ID to be unique.

To enable the Universal-IDs support for your project, pass the `WithGlobalUniqueID` option to the migration.

:::note
Be aware, that `WithGlobalUniqueID` and [versioned migration](versioned-migrations.md) files are not working together.
After understanding the
[risks](https://github.com/ent/ent/blob/8eeb23ce56bcb6ac4ee0354a6c847558586c9a46/dialect/sql/schema/atlas.go#L276-L283),
you can use `WithDeterministicGlobalUniqueID` instead.
:::

```go
package main

Expand Down
45 changes: 38 additions & 7 deletions doc/md/versioned-migrations.md
Expand Up @@ -163,16 +163,47 @@ migrate -source file://migrations -database mysql://root:pass@tcp(localhost:3306
In case you already have an Ent application in production and want to switch over from auto migration to the new
versioned migration, you need to take some extra steps.

1. Create an initial migration file (or several files if you want) reflecting the currently deployed state.
### Create an initial migration file reflecting the currently deployed state

To do this make sure your schema definition is in sync with your deployed version. Then spin up an empty database and
run the diff command once as described above. This will create the statements needed to create the current state of
your schema graph.
To do this make sure your schema definition is in sync with your deployed version. Then spin up an empty database and
run the diff command once as described above. This will create the statements needed to create the current state of
your schema graph.
If you happened to have [universal IDs](migrate.md#universal-ids) enabled before, the above command will create a
file called `.ent_types` containing a list of schema names similar to the following:

2. Configure the tool you use to manage migrations to consider this file as **applied**.
```text title=".ent_types"
atlas.sum ignore
users,groups
```
Once that has been created, one of the migration files will contain statements to create a table called
`ent_types`, as well as some inserts to it:

```sql
CREATE TABLE `users` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT);
CREATE TABLE `groups` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT);
INSERT INTO sqlite_sequence (name, seq) VALUES ("groups", 4294967296);
CREATE TABLE `ent_types` (`id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, `type` text NOT NULL);
CREATE UNIQUE INDEX `ent_types_type_key` ON `ent_types` (`type`);
INSERT INTO `ent_types` (`type`) VALUES ('users'), ('groups');
```

In order to ensure to not break existing code, make sure the contents of that file are equal to the contents in the
table present in the database you created the diff from. For example, if you consider the `.ent_types` file from
above (`users,groups`) but your deployed table looks like the one below (`groups,users`):

| id | type |
|-----|--------|
| 1 | groups |
| 2 | users |

You can see, that the order differs. In that case, you have to manually change both the entries in the
`.ent_types` file, as well in the generated migrations file. As a safety feature, Ent will warn you about type
drifts if you attempt to run a migration diff.

### Configure the tool you use to manage migrations to consider this file as applied

In case of `golang-migrate` this can be done by forcing your database version as
described [here](https://github.com/golang-migrate/migrate/blob/master/GETTING_STARTED.md#forcing-your-database-version).
In case of `golang-migrate` this can be done by forcing your database version as
described [here](https://github.com/golang-migrate/migrate/blob/master/GETTING_STARTED.md#forcing-your-database-version).

## Use a Custom Formatter

Expand Down

0 comments on commit 85f1948

Please sign in to comment.