Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

entc/integration/migrate: add example for renaming columns #2496

Merged
merged 1 commit into from Apr 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions doc/md/migrate.md
Expand Up @@ -300,6 +300,8 @@ options for hooking into schema migration steps.
![atlas-migration-process](https://entgo.io/images/assets/migrate-atlas-process.png)


#### Atlas `Diff` and `Apply` Hooks

Here are two examples that show how to hook into the Atlas `Diff` and `Apply` steps.

```go
Expand Down Expand Up @@ -363,3 +365,54 @@ func main() {
}
}
```

In case a field was renamed in the `ent/schema`, Ent won't detect this change as renaming and will propose `DropColumn`
and `AddColumn` changes in the diff stage. One way to get over this is to use the
[StorageKey](schema-fields.md#storage-key) option on the field and keep the old column name in the database table.
However, using Atlas `Diff` hooks allow replacing the `DropColumn` and `AddColumn` changes with a `RenameColumn` change.

```go
func main() {
client, err := ent.Open("mysql", "root:pass@tcp(localhost:3306)/test")
if err != nil {
log.Fatalf("failed connecting to mysql: %v", err)
}
defer client.Close()
// ...
if err := client.Schema.Create(ctx, schema.WithDiffHook(renameColumnHook)); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}

func renameColumnHook(next schema.Differ) schema.Differ {
return schema.DiffFunc(func(current, desired *atlas.Schema) ([]atlas.Change, error) {
changes, err := next.Diff(current, desired)
if err != nil {
return nil, err
}
for _, c := range changes {
m, ok := c.(*atlas.ModifyTable)
// Skip if the change is not a ModifyTable,
// or if the table is not the "users" table.
if !ok || m.T.Name != user.Table {
continue
}
changes := atlas.Changes(m.Changes)
switch i, j := changes.IndexDropColumn("old_name"), changes.IndexAddColumn("new_name"); {
case i != -1 && j != -1:
// Append a new renaming change.
changes = append(changes, &atlas.RenameColumn{
From: changes[i].(*atlas.DropColumn).C,
To: changes[j].(*atlas.AddColumn).C,
})
// Remove the drop and add changes.
changes.RemoveIndex(i, j)
m.Changes = changes
case i != -1 || j != -1:
return nil, errors.New("old_name and new_name must be present or absent")
}
}
return changes, nil
})
}
```
5 changes: 3 additions & 2 deletions entc/integration/migrate/entv1/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 55 additions & 1 deletion entc/integration/migrate/entv1/mutation.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions entc/integration/migrate/entv1/runtime.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions entc/integration/migrate/entv1/schema/user.go
Expand Up @@ -11,6 +11,7 @@ import (
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
"entgo.io/ent/schema/index"
"github.com/google/uuid"
)

// User holds the schema definition for the User entity.
Expand All @@ -34,6 +35,8 @@ func (User) Fields() []ent.Field {
Optional(),
field.String("renamed").
Optional(),
field.String("old_token").
DefaultFunc(uuid.NewString),
field.Bytes("blob").
Optional().
MaxLen(255),
Expand Down
12 changes: 11 additions & 1 deletion entc/integration/migrate/entv1/user.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions entc/integration/migrate/entv1/user/user.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.