在内置全局 ID 功能标志推出之前,迁移工具曾提供 WithGlobalUniqueID 选项允许用户将迁移模式以使用全局唯一 ID。
该选项现已弃用,取而代之用户应改用全局 ID 功能标志。
现有用户可通过以下步骤迁移模式以使用全局唯一ID。
之前的解决方案利用一个名为 ent_types 的数据表来存储 Ent 模式及其相关的 id 范围之间的映射信息。
新的解决方案使用一个静态配置文件来存储这一映射。
为迁移到新的 全球唯一 ID 功能,可以使用 entfix 命令来将已有的 ent_types 数据表迁移到新的配置文件。
请注意 “ent_types” 数据表可能在不同的应用程序部署环境中会有差异。 特别是使用自动迁移而不是版本化迁移时。 请检查所有部署的所有 “ent_types” 数据表都是一样的。 如果不是这样你可能无法转换为新的全球唯一 ID 功能。
第一步是运行如下命令安装 entfix 工具:
go install entgo.io/ent/cmd/entfix@latest
下一步可以运行 entfix globalid 命令迁移模式到全球唯一 ID 功能。
此命令需要访问数据库读取 ent_types 数据表。
你可以连接到部署的数据库或连接到读取副本,若是版本化迁移连接所有迁移应用后的临时数据库。
entfix globalid --dialect mysql --dsn "root:pass@tcp(localhost:3306)/app" --path ./ent
IMPORTANT INFORMATION
'entfix globalid' will convert the allocated id ranges for your nodes from the
database stored 'ent_types' table to the new static configuration on the ent
schema itself.
Please note, that the 'ent_types' table might differ between different environments
where your app is deployed. This is especially true if you are using
auto-migration instead of versioned migrations.
Please check, that all 'ent_types' tables for all deployments are equal!
Only 'yes' will be accepted to approve.
Enter a value: yes
Success! Please run code generation to complete the process.
通过再次运行代码生成完成迁移后。你应该看到在生成的代码中有一个新的文件 internal/globalid.go ,
仅包含由 const IncrementStarts 开始的一行代码,这表明迁移过程成功完成了。
最后一步是确保迁移设置中移除 migrate.WithGlobalUniqueID(true) 选项。
可选: 保留 ent_types 数据表
你可能期望保留 ent_types 数据表而不是删除它,直到确认无需再进行回滚计算。可以通过使用 Atlas 复合模式做到这一点:
- schema.my.sql
- atlas-hcl
schema "ent" {}
table "ent_types" {
schema = schema.ent
collate = "utf8mb4_bin"
column "id" {
null = false
type = bigint
unsigned = true
auto_increment = true
}
column "type" {
null = false
type = varchar(255)
}
primary_key {
columns = [column.id]
}
index "type" {
unique = true
columns = [column.type]
}
}
data "composite_schema" "ent" {
schema "ent" {
url = "ent://./ent/schema?globalid=static"
}
# This exists to not delete the ent_types table yet.
schema "ent" {
url = "file://./schema.my.hcl"
}
}
env {
name = atlas.env
src = data.composite_schema.ent.url
dev = "docker://mysql/8/ent"
migration {
dir = "file://./ent/migrate/migrations"
}
}
通用 ID(废弃的迁移选项)
默认情况下,SQL 主键在每个表中从 1 开始计数,这意味着不同类型的多个实体可能共享相同的ID。 这与 AWS Neptune 不同,后者使用 UUID 作为节点 ID。
如果你使用 GraphQL 则不能很好地运行,因为它要求对象 ID 是唯一的。
若为项目开启通用 ID 支持,将 WithGlobalUniqueID 选项传入迁移。
版本化迁移用户在使用 MySQL 5.* 数据库上使用 WithGlobalUniqueID 应遵从 此文档。
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.
if err := client.Schema.Create(ctx, migrate.WithGlobalUniqueID(true)); err != nil {
log.Fatalf("failed creating schema resources: %v", err)
}
}
它如何工作? ent 迁移为每个实体(表)分配 1<<32 范围的 ID,并将这些信息存储在生成的代码中(internal/globalid.go)。
例如类型 A 的 ID 范围是 [1,4294967296),类型 B 的范围是 [4294967296,8589934592) 等。
注意如果此选项被启用,可能存在的表的最大数量是 65535。