如何用sqlc与Golang生成多包并共享models.go文件
SQLC多查询包共享单个models.go文件的实现方法
在Golang项目中使用sqlc时,为优化代码组织将SQL查询按文件拆分(objects.sql、object_versions.sql、project_config.sql),并为每个查询文件配置独立Go包。但当前配置会在每个包下重复生成models.go,希望保留各查询包独立、支持同名查询的同时,实现多查询包共享单个models文件。
当前文件结构
查询文件目录:
├── queries │ ├── objects.sql │ ├── object_versions.sql │ └── project_config.sql
当前sqlc.yaml配置(导致重复生成models):
version: "2" sql: - &default name: "common" engine: "postgresql" queries: "./internal/db/queries.sql" schema: "./internal/db/shared_schema.sql" gen: go: &go_defaults package: "common" out: "internal/db/repository/common" sql_package: "pgx/v5" emit_json_tags: true - <<: *default name: "objects" engine: "postgresql" queries: "./internal/db/queries/objects.sql" gen: go: <<: *go_defaults package: "objects" out: "internal/db/repository/objects" - <<: *default name: "object_versions" engine: "postgresql" queries: "./internal/db/queries/object_versions.sql" gen: go: <<: *go_defaults package: "objects_version" out: "internal/db/repository/objects_version" - name: "project_config" engine: "postgresql" queries: "./internal/db/queries/project_config.sql" schema: "./internal/db/shared_schema.sql" gen: go: <<: *go_defaults package: "project_config" out: "./internal/db/repository/project_config"
当前生成的目录结构(每个包都有重复models.go):
├── repository │ ├── common │ │ ├── copyfrom.go │ │ ├── db.go │ │ ├── models.go │ │ └── queries.sql.go │ ├── objects │ │ ├── db.go │ │ ├── models.go │ │ └── objects.sql.go │ ├── objects_version │ │ ├── db.go │ │ ├── models.go │ │ └── object_versions.sql.go │ └── project_config │ ├── db.go │ ├── models.go │ └── project_config.sql.go ├── seed.sql └── shared_schema.sql
实现方案
通过sqlc的emit_models和models_package配置项,先单独生成共享models包,再让各查询包引用该包,避免重复生成models文件。
修改后的sqlc.yaml配置
version: "2" sql: # 1. 单独生成共享models包 - name: "shared_models" engine: "postgresql" schema: "./internal/db/shared_schema.sql" gen: go: package: "models" out: "internal/db/repository/models" sql_package: "pgx/v5" emit_json_tags: true # 2. 定义默认配置:禁用自身models生成,指定共享models包路径 - &default name: "common" engine: "postgresql" queries: "./internal/db/queries.sql" schema: "./internal/db/shared_schema.sql" gen: go: &go_defaults package: "common" out: "internal/db/repository/common" sql_package: "pgx/v5" emit_json_tags: true emit_models: false # 替换为你项目实际的Go模块路径 models_package: "github.com/your-project-path/internal/db/repository/models" # 3. 各查询包继承默认配置,保持独立包结构 - <<: *default name: "objects" queries: "./internal/db/queries/objects.sql" gen: go: <<: *go_defaults package: "objects" out: "internal/db/repository/objects" - <<: *default name: "object_versions" queries: "./internal/db/queries/object_versions.sql" gen: go: <<: *go_defaults package: "objects_version" out: "internal/db/repository/objects_version" - <<: *default name: "project_config" queries: "./internal/db/queries/project_config.sql" gen: go: <<: *go_defaults package: "project_config" out: "./internal/db/repository/project_config"
生成后的目录结构
运行sqlc generate后,会生成独立的共享models包,其他查询包不再生成models.go:
├── repository │ ├── common │ │ ├── copyfrom.go │ │ ├── db.go │ │ └── queries.sql.go │ ├── models # 共享models包 │ │ ├── db.go │ │ └── models.go │ ├── objects │ │ ├── db.go │ │ └── objects.sql.go │ ├── objects_version │ │ ├── db.go │ │ └── object_versions.sql.go │ └── project_config │ ├── db.go │ └── project_config.sql.go ├── seed.sql └── shared_schema.sql
注意事项
models_package需填写完整的Go模块路径(可被其他包import的路径),替换为你项目实际的模块前缀。- 所有查询包会自动import共享models包,生成的查询代码会直接使用该包的模型定义。
- 后续schema变更时,重新运行
sqlc generate即可更新共享models,所有查询包同步使用最新模型。
内容的提问来源于stack exchange,提问作者TalesMGodois
相关产品推荐
相关产品推荐

