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 ./...之后,从后到前的代码就全部生成完了。

参考资料

相关推荐
沐风清扬15 分钟前
Solr-搜索引擎-入门到精通
后端·搜索引擎·php·solr
在努力的韩小豪2 小时前
【微服务架构】本地负载均衡的实现(基于随机算法)
后端·spring cloud·微服务·架构·负载均衡
声声codeGrandMaster6 小时前
Django项目入门
后端·mysql·django
千里码aicood6 小时前
【2025】基于springboot+vue的医院在线问诊系统设计与实现(源码、万字文档、图文修改、调试答疑)
vue.js·spring boot·后端
yang_love10117 小时前
Spring Boot 中的 @ConditionalOnBean 注解详解
java·spring boot·后端
Pandaconda7 小时前
【后端开发面试题】每日 3 题(二十)
开发语言·分布式·后端·面试·消息队列·熔断·服务限流
鱼樱前端8 小时前
mysql事务、行锁、jdbc事务、数据库连接池
java·后端
Adellle8 小时前
MySQL
数据库·后端·mysql
JavaGuide9 小时前
Kafka 4.0 正式发布,彻底抛弃 Zookeeper,队列功能来袭!
后端·kafka
轻松Ai享生活9 小时前
2030年的大模型将会是什么样的?机械可解释性又是什么?
人工智能·后端·面试