自定义解码器实战让 deno-postgres 按你的规则解析查询结果【免费下载链接】postgresPostgreSQL driver for Deno项目地址: https://gitcode.com/gh_mirrors/postgr/postgresdeno-postgres 是 Deno 生态中最流行的 PostgreSQL 驱动之一它把数据库返回的原始字符串自动解析成 JavaScript 原生类型让开发者几乎感觉不到类型转换的存在。但默认的解析规则并不总能满足业务需求——比如你想把布尔值转成 0/1、把日期直接变成 dayjs 对象、或者给 JSONB 字段做二次加工。这时deno-postgres 自定义解码器custom decoders就是你最趁手的工具。本文将用最少的代码带你从零掌握自定义解码器的配置方法、优先级规则和数组类型处理技巧。为什么你需要自定义解码器3 个真实场景默认情况下deno-postgres 会把bool解析成布尔值、int4解析成数字、jsonb解析成对象源码见query/decoders.ts。但实际项目中你往往会遇到这些痛点格式不统一想让所有日期字段统一转成 dayjs 对象方便链式操作语义不匹配把数据库的t/f布尔值映射成业务需要的1/0甚至中文字符串数据需要预处理查询结果里的 JSON 字段希望自动脱敏、补默认值或改字段名。自定义解码器能让你在数据到达业务代码之前就按自己的规则完成转换一处配置、全局生效省去每处查询后的重复加工。快速上手第一个自定义解码器只需 5 行配置自定义解码器通过客户端配置项controls.decoders注册它是一个类型 → 解码函数的映射表。来看一个最简单的例子import { Client, Oid } from ./mod.ts; const client new Client({ database: some_db, user: some_user, controls: { decoders: { // 方式一用类型名作为 key bool: (value: string) value t ? 1 : 0, // 方式二用 OID 数字作为 key16 就是 bool 的 OID [Oid.bool]: (value: string) value t ? 1 : 0, }, }, }); await client.connect(); const { rows } await client.queryObject(SELECT 1 1 AS ok); console.log(rows); // [{ ok: 1 }]解码函数的签名固定为(value: string, oid: number, parseArray) unknown第一个参数是数据库返回的原始字符串第二个是列类型的 OID 编号第三个是数组解析辅助函数后面会用到。Oid对象从mod.ts中导出完整类型清单见query/oid.ts。用类型名还是 OID 编号推荐这样选deno-postgres 支持两种 key 写法各有适用场景写法示例适用场景类型名bool、int4、jsonb代码可读性好推荐日常使用OID 数字16、23、3802处理自定义类型、枚举类型等冷门类型时更精准小提示当同一个类型同时注册了数字 key 和名称 key 时数字 key 的优先级更高。也就是说[Oid.bool]会覆盖bool的配置这一点在排查为什么我的解码器没生效时非常重要。数组类型不用怕解码器自动套用到每个元素很多新手会担心int4[]、text[]这类数组类型要单独写解码逻辑。好消息是deno-postgres 已经帮你处理好了如果你只为int4定义了解码器查询int4[]数组时驱动会自动用parseArray见query/array_parser.ts把数组拆开对每个元素套用同一个解码器。controls: { decoders: { // 只注册 int4 的解码器 int4: (value: string) parseInt(value, 10) * 100, }, } // SELECT ARRAY[2, 2, 3] AS scores // 结果{ scores: [200, 200, 300] }如果你想对数组整体做特殊处理比如过滤、去重也可以直接注册int4_array这样的数组类型解码器它会优先于基础类型自动套用逻辑执行controls: { decoders: { int4_array: (value: string, _oid, parseArray) parseArray(value, (v) parseInt(v, 10) * 10), }, }三种解码方式如何共存记住这条优先级链deno-postgres 提供了两种全局策略和一种局部覆盖理解它们的优先级才能写出不踩坑的代码自定义解码器decoders优先级最高命中即生效decodeStrategy: string把所有字段以原始字符串返回由你自行解析默认 auto 策略按内置规则解析成 JS 原生类型。controls: { // 全局返回字符串 decodeStrategy: string, decoders: { // 但布尔字段仍然走自定义解码器 bool: (value: string) ({ value: value t, type: boolean }), }, }这条规则在query/decode.ts的decode函数中有清晰体现先查自定义解码器再看全局策略最后才走内置解析。实战案例一次配置格式化 JSONB 与日期把前面学到的技巧组合起来看看一个生产可用的配置长什么样import { Client, Oid } from ./mod.ts; const client new Client({ database: some_db, user: some_user, controls: { decoders: { // JSONB 字段自动加工 jsonb: (value: string) { const obj JSON.parse(value); obj.created_at new Date(obj.created_at).toISOString(); return obj; }, // 日期字段自动加一天模拟时区修正 1082: (value: string) { const d new Date(value); return new Date(d.setDate(d.getDate() 1)); }, }, }, });同样的解码规则在Client、Pool和Transaction中都能使用一套配置覆盖所有查询路径维护成本极低。官方测试里还有更多组合玩法可以参考tests/query_client_test.ts中的 Custom decoders 用例。写在最后自定义解码器是 deno-postgres 提供的一项小而美的能力配置直观、优先级清晰、对数组类型开箱即用。当你觉得默认类型解析不够聪明时不妨先试试它而不是在每个查询后面写一堆 map 函数。想深入了解实现细节可以翻阅项目中的connection/connection_params.ts类型定义和query/decode.ts解码入口你也可以直接克隆源码仓库在本地跑一遍测试用例亲手感受自定义解码器的完整工作流程。【免费下载链接】postgresPostgreSQL driver for Deno项目地址: https://gitcode.com/gh_mirrors/postgr/postgres创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考