Squirrel处理可空查询参数的3种实用技巧:终极变通指南
【免费下载链接】squirrel
🐿️ Type safe SQL in Gleam
Squirrel 是 Gleam 生态中一款出色的类型安全 SQL代码生成工具:你在*.sql文件里写查询,它自动生成带正确类型与编解码器的函数。但在处理**可空查询参数(nullable query parameters)**时,Squirrel 有一个官方承认的限制——Postgres 不会暴露参数的可空性元数据,因此 Squirrel 无法为可空列自动推断出Option类型。别担心,本文给出 3 种经过官方认可的实用变通技巧,帮你快速绕开这个限制 💡
为什么 Squirrel 无法自动推断可空参数?
先看一个典型场景。假设有这样一张表和一个更新查询:
create table if not exists recipe( id int primary key, title text not null, author uuid, -- 可能缺失 description text -- 可能缺失 ); -- update_recipe_author.sql update recipe set author = $1 where id = $2;Squirrel 生成的函数签名会是update_recipe_author(db, arg1: Uuid, arg2: Int)——注意arg1是Uuid而非Option(Uuid)。原因是 Squirrel 通过检查 Postgres 暴露的元数据来推断类型,而参数侧($1、$2)Postgres 不提供可空信息(详见 README.md 的 FAQ 部分,以及参数解析逻辑 src/squirrel/internal/database/postgres.gleam)。
⚠️ 注意区分:返回列的可空性 Squirrel 是能自动推断的(它会检查
not null约束,甚至解析查询执行计划来判断 LEFT JOIN 产生的空值),唯独参数这一侧需要变通。
技巧一:拆分为两条查询,各司其职
当可空参数很少、逻辑简单时,最推荐的做法是干脆定义两条查询:一条写入真实值,一条显式写入null:
-- set_recipe_author.sql:设置作者 update recipe set author = $1 where id = $2;-- remove_recipe_author.sql:清除作者 update recipe set author = null where id = $2;优点:SQL 简单直白、函数语义清晰(set_recipe_authorvsremove_recipe_author),调用方一看就懂。这是官方 FAQ 给出的首选方案,适合 90% 的简单场景 ✅
技巧二:哨兵值 + CASE WHEN 转换 null
当可空参数很多、或查询逻辑复杂不适合复制多份时,可以挑选一个"哨兵值"(sentinel value)代表null,在 SQL 内部做转换:
-- update_recipe.sql update recipe set author = case $1 when '00000000-0000-0000-0000-000000000000' then null else $1 end, description = case $2 when "" then null else $2 end where id = $3;调用方传入"全零 UUID"或空字符串,就表示"清空该字段"。查询保持单文件、单函数,避免了查询爆炸。
技巧三:用 SQL 辅助函数封装 null 转换逻辑
技巧二的查询写多了会变得臃肿。记住一句话:SQL 也是代码,同样值得重构🛠️ 把哨兵转换抽成数据库函数:
create function string_or_null(value text) returns text language sql immutable return nullif(value, "");查询立刻变得清爽:
-- update_recipe.sql update recipe set author = uuid_or_null($1), description = string_or_null($2) where id = $3;优点:转换规则只写一次、处处复用,主查询回归简洁;nullif这类函数本身就是 Postgres 的标准能力。
3 种技巧选型速查表
| 场景 | 推荐技巧 | 关键考量 |
|---|---|---|
| 可空参数 ≤ 2 个、逻辑简单 | 技巧一:拆分两条查询 | 语义最清晰,零额外复杂度 |
| 可空参数多、查询复杂 | 技巧二:哨兵值 + CASE | 单文件单函数,避免查询膨胀 |
| 多个查询都要做 null 转换 | 技巧三:SQL 辅助函数 | 规则复用,查询保持整洁 |
改完 SQL 后运行gleam run -m squirrel重新生成代码,并在 CI 中用gleam run -m squirrel check校验代码是否过期(参见 README.md 的 CLI Commands 一节)。
补充:返回列可空性 Squirrel 能自动推断
如果你的痛点其实是"返回值该不该是Option",Squirrel 已经替你解决了:它检查列的not null约束,并解析explain查询计划识别 LEFT/FULL JOIN 引入的空值(实现见 src/squirrel/internal/database/postgres.gleam 中resolve_returns的逻辑)。推断不准时还可以用别名后缀强制指定:列名以?结尾强制可空、以!结尾强制非空。更多背景可参考 CHANGELOG.md 中关于 optional 类型修复的记录。
写在最后
可空参数是 Squirrel 当前唯一需要你"多想一步"的地方,但三种变通技巧都很轻量:简单就拆查询,复杂就用哨兵值,重复就抽函数。结合check子命令,你可以放心地把这套模式固化进团队规范,继续享受 Squirrel 带来的类型安全 SQL 体验 🐿️
【免费下载链接】squirrel
🐿️ Type safe SQL in Gleam
相关推荐
60,000+ 项目都在用的 AGENTS.md:3步让AI编码助手读懂你的项目
60,000+ 项目都在用的 AGENTS.md:3步让AI编码助手读懂你的项目 每次跟AI编码助手开新会话,你都得重复交代一遍:依赖用 pnpm、测试要跑过再
文档AI Agent前端Fiddler中文版完整教程:HTTP/HTTPS流量捕获与分析实战
Fiddler中文版完整教程:HTTP/HTTPS流量捕获与分析实战 Fiddler Web Debugger中文版是一款功能强大的Web调试工具,能够帮助开发
开发工具接口测试Django SQL Explorer 参数化查询终极实战指南:10个实用技巧提升数据查询效率
Django SQL Explorer 参数化查询终极实战指南:10个实用技巧提升数据查询效率 Django SQL Explorer 是一个强大的数据探索工具
后端数据分析开发工具大模型
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考