Ent代码生成工具链

Ent代码生成工具链

Ent是Facebook开源的一个GO语言的ORM框架。它提供了一系列的工具,可以做到:

  1. SQL生成schema;
  2. schema生成protobuf的message;
  3. schema生成gPRC的service。

创建go项目

bash 复制代码
go mod init entimport-example

初始化ent的文件夹

bash 复制代码
mkdir ./ent/schema

SQL生成schema

text 复制代码
Usage of entimport:

  -dsn string
        data source name (connection information), for example:
        "mysql://user:pass@tcp(localhost:3306)/dbname"
        "postgres://user:pass@host:port/dbname"
  -exclude-tables value
        comma-separated list of tables to exclude
  -schema-path string
        output path for ent schema (default "./ent/schema")
  -tables value
        comma-separated list of tables to inspect (all if empty)

MySQL

sql 复制代码
CREATE TABLE users
(
    id        bigint auto_increment PRIMARY KEY,
    age       bigint       NOT NULL,
    name      varchar(255) NOT NULL,
    last_name varchar(255) NULL comment 'surname'
);

CREATE TABLE cars
(
    id          bigint auto_increment PRIMARY KEY,
    model       varchar(255) NOT NULL,
    color       varchar(255) NOT NULL,
    engine_size mediumint    NOT NULL,
    user_id     bigint       NULL,
    CONSTRAINT cars_owners FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL
);

导出表结构:

bash 复制代码
go run -mod=mod ariga.io/entimport/cmd/entimport \
                -dsn "mysql://root:pass@tcp(localhost:3306)/entimport"

Postgresql

sql 复制代码
CREATE TABLE users (
    id bigserial PRIMARY KEY,
    age bigint NOT NULL,
    name varchar(255) NOT NULL,
    last_name varchar(255) NULL
);

CREATE TABLE cars (
    id bigserial PRIMARY KEY,
    model varchar(255) NOT NULL,
    color varchar(255) NOT NULL,
    engine_size int NOT NULL,
    user_id bigint NULL,
    CONSTRAINT cars_owners FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL
);

导出表结构:

bash 复制代码
go run -mod=mod ariga.io/entimport/cmd/entimport \
                -dsn "postgres://postgres:123456@localhost:5432/entimport?sslmode=disable"

schema生成proto

我们首先需要修改生成出来的Schema,修改ent/schema/user.goAnnotations方法:

go 复制代码
func (User) Annotations() []schema.Annotation {
    return []schema.Annotation{
        entproto.Message(),
        entproto.Service(
            entproto.Methods(
                entproto.MethodCreate | entproto.MethodGet | entproto.MethodList | entproto.MethodBatchCreate
                ),
        ),
    }
}

其中,entproto.Message()标识着将为该表生成proto的messageentproto.Service标志着为该表生成gRPC的service,而entproto.Methods则可以控制生成的service中的方法。

然后,还需要给每一个字段添加entproto.Field

go 复制代码
// Fields of the User.
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").
            Unique().
            Annotations(
                entproto.Field(2),
            ),
        field.String("email_address").
            Unique().
            Annotations(
                entproto.Field(3),
            ),
    }
}

修改完代码,需要先生成ent代码:

bash 复制代码
go run -mod=mod entgo.io/ent/cmd/ent generate ./schema

现在就可以生成proto文件了:

bash 复制代码
go run -mod=mod entgo.io/contrib/entproto/cmd/entproto -path ./schema

我们可以把这两个命令写入到ent/generate.go:

go 复制代码
package ent

//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema
//go:generate go run -mod=mod entgo.io/contrib/entproto/cmd/entproto -path ./schema

这时候就可以执行下面的命令来执行生成:

go 复制代码
go generate ./...

生成的代码为:

bash 复制代码
ent/proto
└── entpb
    ├── entpb.proto
    └── generate.go

需要注意的是ent/proto/entpb/generate.go中的生成命令需要做一定的修改:

go 复制代码
package entpb

//go:generate protoc --go_out=.. --go-grpc_out=.. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative --entgrpc_out=.. --entgrpc_opt=paths=source_relative,schema_path=..\..\schema entpb.proto

利用ent/proto/entpb/generate.go,我们可以从proto生成go的代码。

在生成之前,我们还需要安装protoc的3个插件:

bash 复制代码
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install entgo.io/contrib/entproto/cmd/protoc-gen-entgrpc@master

当我们再次执行go generate ./...之后,从后到前的代码就全部生成完了。

参考资料

相关推荐
子兮曰2 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰2 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝2 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码2 天前
别再前后端各写一套表单校验了
java·后端
大勇前进2 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu2 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile2 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白802 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙2 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端
盖伦发发2 天前
软件工程SOLID 五大设计原则
后端·软件工程