Ent代码生成工具链:从SQL到gRPC的代码生成之路

后端 潘老师 4周前 (03-25) 22 ℃ (0) 扫码查看

今天要给大家介绍的Ent,是Facebook开源的一款Go语言ORM框架,它配备的代码生成工具链功能十分强大。借助这个工具链,我们可以实现从SQL生成schema,再由schema生成protobuf的message以及gRPC的service,下面为大家详细讲解。

一、搭建项目基础

在使用Ent工具链前,得先创建一个Go项目,并初始化Ent相关的文件夹。

1.创建Go项目:在命令行中执行以下命令,创建一个名为entimport-example的Go项目:

go mod init entimport-example

这个命令就像是给项目搭建了一个“框架”,为后续的开发工作做好准备。
2. 初始化Ent文件夹:接着,运行下面的命令来创建Ent的schema文件夹,它用于存放Ent的模式定义文件:

mkdir ./ent/schema

这个文件夹就好比是项目中的一个“仓库”,专门用来存放与数据结构相关的重要信息。

二、从SQL生成schema

Ent工具链支持从SQL数据库中提取表结构,并生成相应的Ent schema。不过在操作前,我们要清楚工具的使用参数。

  1. Entimport工具参数说明entimport工具用于从SQL生成schema,它有几个重要参数:
    • -dsn:数据源名称,也就是数据库的连接信息。比如MySQL的连接信息格式为"mysql://user:pass@tcp(localhost:3306)/dbname" ,PostgreSQL的则是"postgres://user:pass@host:port/dbname"。这个参数就像是项目与数据库之间的“桥梁”,让程序知道该连接哪个数据库。
    • -exclude-tables:以逗号分隔的表名列表,表示要排除的表。
    • -schema-path:Ent schema的输出路径,默认是"./ent/schema"
    • -tables:以逗号分隔的表名列表,指定要检查的表,如果为空则表示检查所有表。
  2. MySQL数据库操作示例:假设我们有如下MySQL数据库表结构:
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
);

要导出这些表的结构生成Ent schema,在命令行执行:

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

这里的命令就像是给工具下达的“指令”,告诉它从哪个MySQL数据库中提取表结构信息。
3. PostgreSQL数据库操作示例:PostgreSQL的表结构定义稍有不同,例如:

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
);

导出表结构的命令为:

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

通过这些操作,就能根据不同的SQL数据库表结构生成对应的Ent schema了。

三、从schema生成proto

生成Ent schema后,还能进一步生成proto文件,不过在此之前需要对生成的Schema进行一些修改。

  1. 修改Schema的Annotations方法:打开ent/schema/user.go文件,修改其中的Annotations方法,添加如下代码:
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中包含哪些方法。
2. 为字段添加entproto.Field:同时,还要给每个字段添加entproto.Field,例如:

// 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),
            ),
    }
}

这一步就像是给每个字段贴上了特殊的“标签”,让生成proto文件时能准确处理每个字段。
3. 生成Ent代码和proto文件:修改完代码后,先执行以下命令生成Ent代码:

go run -mod=mod entgo.io/ent/cmd/ent generate ./schema

然后再执行下面的命令生成proto文件:

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

为了方便后续操作,我们可以把这两个命令写入到ent/generate.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 generate ./...

执行完上述操作后,会生成ent/proto目录,里面包含entpb文件夹,结构如下:

ent/proto
└── entpb
    ├── entpb.proto
    └── generate.go

不过,ent/proto/entpb/generate.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

修改后,利用这个文件就能从proto生成Go的代码。但在生成之前,还需要安装protoc的3个插件:

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 ./...,整个从SQL到gRPC的代码就全部生成完毕了。

通过以上详细介绍,相信大家对Ent代码生成工具链的使用有了更深入的了解,在实际开发中可以利用它高效地生成所需代码啦。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/16269.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】