跳到主要内容

在 Ent Schema 中使用 Postgres 扩展

Postgres 扩展是附加模块,通过提供新的数据类型、运算符、函数、过程语言等功能来扩展数据库的能力。

本指南介绍了如何定义一个使用 PostGIS 扩展提供的数据类型的 schema 字段,并配置 schema 迁移功能,使用 Atlas 将 Postgres 扩展安装和 Ent schema 作为一个迁移单元进行管理。

Atlas 对扩展的支持仅限 Pro 用户使用。 要使用此功能,请运行:

atlas login

安装 Atlas

To install the latest release of Atlas, simply run one of the following commands in your terminal, or check out the Atlas website:

curl -sSf https://atlasgo.sh | sh

登录 Atlas

$ atlas login a8m
您已成功连接到 Atlas Cloud 上的 "a8m" 账户。

复合 Schema

ent/schema 包主要用于定义 Ent 类型(对象)、其字段、边和逻辑。像 postgishstore 这样的扩展在 Ent schema 中没有直接表示。Postgres 扩展可以在 Postgres 数据库中安装一次,并可在不同 schema 中多次使用。

为了将我们的 PostgreSQL schema 迁移扩展到包含扩展和 Ent 类型,我们配置 Atlas 从复合 Schema数据源读取 schema 状态。请按照以下步骤为您的项目进行配置:

1. 创建一个 schema.sql 文件,定义数据库所需的扩展。同样地,您可以使用 Atlas Schema HCL 语言定义扩展:

schema.sql
-- 安装 PostGIS 扩展。
CREATE EXTENSION postgis;

2. 在您的 Ent schema 中,定义一个使用扩展提供的数据类型的字段。在此示例中,我们使用 postgis 扩展提供的 GEOMETRY(Point, 4326) 数据类型:

ent/schema/user.go
// User 的字段。
func (User) Fields() []ent.Field {
return []ent.Field{
field.Bytes("location").
// 理想情况下,我们会使用自定义 GoType
// 来表示 "geometry" 类型。
SchemaType(map[string]string{
dialect.Postgres: "GEOMETRY(Point, 4326)",
}),
}
}

3. 创建一个简单的 atlas.hcl 配置文件,其中包含一个 composite_schema,同时包含 schema.sql 中定义的扩展和您的 Ent schema:

atlas.hcl
data "composite_schema" "app" {
# 首先安装扩展(PostGIS)。
schema "public" {
url = "file://schema.sql"
}
# 然后,加载 Ent schema。
schema "public" {
url = "ent://ent/schema"
}
}

env "local" {
src = data.composite_schema.app.url
dev = "docker://postgis/latest/dev"
format {
migrate {
diff = "{{ sql . \" \" }}"
}
}
}

使用指南

设置好复合 schema 后,我们可以使用 atlas schema inspect 命令获取其表示,为其生成 schema 迁移,将其应用到数据库等。以下是一些帮助您开始使用 Atlas 的命令:

检查 Schema

atlas schema inspect 命令通常用于检查数据库。但我们也可以使用它来检查我们的 composite_schema 并打印其 SQL 表示:

atlas schema inspect \
--env local \
--url env://src \
--format '{{ sql . }}'

上述命令将打印以下 SQL。

-- 添加名为 "public" 的新 schema
CREATE SCHEMA IF NOT EXISTS "public";
-- 设置 schema 注释:"public"
COMMENT ON SCHEMA "public" IS 'standard public schema';
-- 创建扩展 "postgis"
CREATE EXTENSION "postgis" WITH SCHEMA "public" VERSION "3.4.2";
-- 创建 "users" 表
CREATE TABLE "public"."users" ("id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "location" public.geometry(point,4326) NOT NULL, PRIMARY KEY ("id"));
扩展是数据库级对象

尽管 CREATE EXTENSION 命令支持 SCHEMA 参数,但它仅指示扩展对象将安装在何处。扩展本身是在数据库级别安装的,不能多次加载到不同的 schema 中。

因此,为避免与其他 schema 冲突,在使用扩展时,迁移的范围应设置为数据库级别,对象使用 schema 名称进行限定。因此,在 atlas.hcl 文件中,开发数据库 URL 中的 search_path 已被移除。

为 Schema 生成迁移

要生成 schema 的迁移,请运行以下命令:

atlas migrate diff \
--env local

注意将创建一个新的迁移文件,其内容如下:

migrations/20240712090543.sql
-- 创建扩展 "postgis"
CREATE EXTENSION "postgis" WITH SCHEMA "public" VERSION "3.4.2";
-- 创建 "users" 表
CREATE TABLE "public"."users" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"location" public.geometry(point,4326) NOT NULL,
PRIMARY KEY ("id")
);

应用迁移

要将上述生成的迁移应用到数据库,请运行以下命令:

atlas migrate apply \
--env local \
--url "postgres://postgres:pass@localhost:5432/database?search_path=public&sslmode=disable"
直接在数据库上应用 Schema

有时需要直接向数据库应用 schema 而不生成迁移文件。例如,在实验 schema 更改、启动测试数据库等情况下。在这种情况下,您可以使用以下命令直接将 schema 应用到数据库:

atlas schema apply \
--env local \
--url "postgres://postgres:pass@localhost:5432/database?sslmode=disable"

或者,使用 Atlas Go SDK

ac, err := atlasexec.NewClient(".", "atlas")
if err != nil {
log.Fatalf("failed to initialize client: %w", err)
}
// 自动使用期望的 schema 更新数据库。
// 另一种选择是手动使用 'migrate apply' 或 'schema apply'。
if _, err := Ac.SchemaApply(ctx, &atlasexec.SchemaApplyParams{
Env: "local",
URL: "postgres://postgres:pass@localhost:5432/database?sslmode=disable",
AutoApprove: true,
}); err != nil {
log.Fatalf("failed to apply schema changes: %w", err)
}

本指南的代码可以在 GitHub 上找到。