数据库迁移
在应用程序初始化过程中运行自动迁移逻辑:
Create
创建你项目 ent
部分所需的的数据库资源 。 默认情况下,Create
以“append-only”模式工作;这意味着,它只创建新表和索引,将列追加到表或扩展列类型。 例如,将int
改为bigint
。
想要删除列或索引怎么办?
删除资源
WithDropIndex
和 WithDropColumn
是用于删除表列和索引的两个选项。
package main
import (
"context"
"log"
"<project>/ent"
"<project>/ent/migrate"
)
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()
ctx := context.Background()
// Run migration.
err = client.Schema.Create(
ctx,
migrate.WithDropIndex(true),
migrate.WithDropColumn(true),
)
if err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}
为了在调试模式下运行迁移 (打印所有SQL查询),请运行:
This does not work well if you work with , which requires the object ID to be unique.
To enable the Universal-IDs support for your project, pass the WithGlobalUniqueID
option to the migration.
package main
import (
"context"
"log"
"<project>/ent/migrate"
)
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()
ctx := context.Background()
// Run migration.
if err := client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true)); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}
How does it work? ent
migration allocates a 1<<32 range for the IDs of each entity (table), and store this information in a table named ent_types
. For example, type A
will have the range of [1,4294967296)
for its IDs, and type B
will have the range of [4294967296,8589934592)
, etc.
Note that if this option is enabled, the maximum number of possible tables is 65535.
Offline Mode
Offline mode allows you to write the schema changes to an io.Writer
before executing them on the database. It’s useful for verifying the SQL commands before they’re executed on the database, or to get an SQL script to run manually.
Write changes to a file
package main
import (
"context"
"log"
"os"
"<project>/ent"
"<project>/ent/migrate"
)
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()
ctx := context.Background()
// Dump migration changes to an SQL script.
f, err := os.Create("migrate.sql")
if err != nil {
}
defer f.Close()
if err := client.Schema.WriteTo(ctx, f); err != nil {
log.Fatalf("failed printing schema changes: %v", err)
}
}
By default, ent
uses foreign-keys when defining relationships (edges) to enforce correctness and consistency on the database side.
However, ent
also provide an option to disable this functionality using the WithForeignKeys
option. You should note that setting this option to false
, will tell the migration to not create foreign-keys in the schema DDL and the edges validation and clearing must be handled manually by the developer.
We expect to provide a set of hooks for implementing the foreign-key constraints in the application level in the near future.
Migration Hooks
The framework provides an option to add hooks (middlewares) to the migration phase. This option is ideal for modifying or filtering the tables that the migration is working on, or for creating custom resources in the database.
package main
import (
"context"
"log"
"<project>/ent"
"<project>/ent/migrate"
"entgo.io/ent/dialect/sql/schema"
)
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()
ctx := context.Background()
// Run migration.
err = client.Schema.Create(
ctx,
schema.WithHooks(func(next schema.Creator) schema.Creator {
return schema.CreateFunc(func(ctx context.Context, tables ...*schema.Table) error {
// Run custom code here.
return next.Create(ctx, tables...)
})
}),
)
if err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}