sqlc生成代码需严格满足格式:sql文件中每条语句必须以顶格-- name: xxx :many开头(空格不可少、不可缩进、不可重复),且语句间需空行;:one/:many/:exec须小写;路径需用glob如./query/*.sql;emit_db_tags: true和emit_context: true须显式启用,否则字段扫描失败或无context支持。

别用 ORM 或手写模板生成 CRUD——sqlc 是当前最稳的 Go SQL 代码生成方案。它不运行时拼 SQL,不反射,不 magic string,只把 SELECT id, name FROM users 编译成 func (q *Queries) GetUsers(ctx context.Context) ([]User, error),类型错、字段改名、JOIN 结构嵌套问题全在编译期暴露。
sqlc generate 报 “no statements found” 怎么办
这不是语法错误,是 sqlc 根本没读到有效 SQL 语句。它只认一种入口:顶格写的 -- name: GetUsers :many 注释,且必须带空格、不能缩进、不能重复。
-
--name: GetUser(缺空格)、-- name: GetUser(有缩进)、-- name: GetUser出现两次 → 全部静默跳过 - .sql 文件里每条语句之间必须有空行;
:one/:many/:exec必须小写,写成:ONE或:One就无效 - VS Code 的 SQLTools 插件可能插入不可见 Unicode 字符,建议用
cat -A query/users.sql检查 - 确保
sqlc.yaml中queries路径是 glob 形式,比如./query/*.sql,不是./query/users.sql(除非你真只读一个文件)
生成的代码编译失败:undefined User 或 missing db tag
常见原因是 schema 没加载或字段映射崩了。sqlc 不会凭空造 struct,它靠解析 CREATE TABLE DDL 来推字段类型和名字。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
-
schema路径下必须是真实 DDL(如CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)),不能是空文件、连接串或CREATE EXTENSION(PostgreSQL 用户务必删掉或注释掉这类语句) - 启用
emit_db_tags: true(默认开),否则生成的 struct 字段没有db:"user_id"标签,database/sql的Scan会失败 - 字段名含下划线(如
user_id_v2)默认映射为UserIDV2;若数据库列是user_id_2,则映射成UserID2—— 命名不一致会导致 scan 零值 - 如果用了
AS别名(SELECT name AS full_name),struct 字段的db标签必须写成db:"full_name"
怎么让生成函数带 context.Context 参数
老项目升级或新建时容易漏掉这个开关:emit_context: true 不开,所有方法签名都是 GetUser(id int) (User, error),没法超时控制,线上易出长尾请求。
- 必须显式加在
sqlc.yaml的packages下(v1.14+ 默认不开启) - 开了之后签名变成
GetUser(ctx context.Context, id int) (User, error),但 sqlc 不管你传的是context.Background()还是context.WithTimeout(),只负责透传 - 事务场景下,
ctx应该来自外层 handler,不是在Queries初始化时塞进去的 - 别手动改生成代码加 ctx——下次
sqlc generate就被覆盖
PostgreSQL jsonb / uuid / timestamptz 字段生成后怎么用
sqlc 默认把 jsonb 当 []byte、uuid 当 string、timestamptz 当 time.Time,看着能跑,实际常踩坑。
-
jsonb字段想映射成map[string]interface{}?不行。得自己实现sql.Scanner和driver.Valuer,或用pgtype.JSONB配合 - 要让
uuid字段生成github.com/google/uuid.UUID类型,必须在sqlc.yaml加overrides:
overrides:
- db_type: "uuid"
go_type: "github.com/google/uuid.UUID"
go_imports:
- "github.com/google/uuid"
timestamptz 映射为 time.Time 没问题,但时区丢失往往是因为数据库连接串没加 timezone=UTC,不是 sqlc 的锅text[])默认也是 []byte,需同理 override 或自定义扫描逻辑最常被忽略的一点:sqlc 生成的是纯函数,不管理连接、不注册驱动、不初始化 pool。你传进去的 *sql.DB 必须已调用 sql.Open 并完成 SetMaxOpenConns 等配置,否则运行时报 nil pointer 或 driver: bad connection —— 这些错误跟 sqlc 本身无关,但新手总以为是生成器坏了。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










