使用LEFT JOIN时SQLC生成代码扫描NULL列报错求助
问题:SQLC生成的结构体未处理LEFT JOIN导致的可空字段
我修改了PostgreSQL中的表结构,将a表的b_id字段设为可空:
CREATE TABLE a ( a_name varchar NOT NULL, b_id BIGINT -- 之前为NOT NULL,现在改为可空 ); CREATE TABLE b ( id BIGSERIAL, b_name varchar NOT NULL );
a表的b_id字段存在指向b表id的外键约束。
我有一个关联查询返回b_name,示例如下:
-- name: List :many SELECT a_name, b_name FROM a LEFT JOIN b ON b.id = a.b_id -- 当a.b_id为NULL时,b_name会返回NULL
由于使用LEFT JOIN,当a.b_id为NULL时,查询返回的b_name即为NULL。
但SQLC生成的Row结构体中,BName被定义为非空的string类型:
type ListRow struct { AName string `json:"a_name"` BName string `json:"b_name"` }
我已经在配置中使用gobuffalo nulls重载,本该生成可空类型,结果导致扫描错误:
"sql: Scan error on column index 1, name \"b_name\": converting NULL to string is unsupported"
解决方案
确认sqlc配置文件的null重载配置
确保在sqlc.yaml中正确配置了gobuffalo nulls的重载规则,明确指定可空的数据库类型对应到可空Go类型:sql: - schema: "schema.sql" queries: "queries.sql" engine: "postgresql" gen: go: package: "db" out: "db" overrides: - go_type: "github.com/gobuffalo/nulls.String" db_type: "varchar" nullable: true - go_type: "github.com/gobuffalo/nulls.Int64" db_type: "bigint" nullable: true注意要覆盖所有可能出现可空情况的数据库类型,并且
nullable: true不能遗漏。显式标记查询中的可空字段
在SQL查询中,给可能返回NULL的字段添加/* sqlc:nullable */注释,强制sqlc生成可空类型:-- name: List :many SELECT a_name, b_name /* sqlc:nullable */ FROM a LEFT JOIN b ON b.id = a.b_id这个注释会告诉sqlc该字段存在返回NULL的可能,忽略表结构中的非空定义(因为LEFT JOIN导致的外层可空)。
检查sqlc版本
旧版本的sqlc在处理LEFT JOIN带来的字段可空性时可能存在解析缺陷,升级到最新稳定版可以解决这类兼容性问题。验证表结构解析
确保sqlc正确读取了最新的表结构,可以尝试重新生成代码,或者清理sqlc的缓存后再生成,避免旧的表结构缓存导致错误。
内容的提问来源于stack exchange,提问作者slexov
相关产品推荐
相关产品推荐

