news 2026/8/20 19:23:35

自定义解码器实战:让 deno-postgres 按你的规则解析查询结果

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
自定义解码器实战:让 deno-postgres 按你的规则解析查询结果

自定义解码器实战:让 deno-postgres 按你的规则解析查询结果

【免费下载链接】postgresPostgreSQL driver for Deno项目地址: https://gitcode.com/gh_mirrors/postgr/postgres

deno-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 数字作为 key(16 就是 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 写法,各有适用场景:

写法示例适用场景
类型名boolint4jsonb代码可读性好,推荐日常使用
OID 数字16233802处理自定义类型、枚举类型等冷门类型时更精准

小提示:当同一个类型同时注册了数字 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 提供了两种全局策略和一种局部覆盖,理解它们的优先级才能写出不踩坑的代码:

  1. 自定义解码器(decoders):优先级最高,命中即生效;
  2. decodeStrategy: "string":把所有字段以原始字符串返回,由你自行解析;
  3. 默认 auto 策略:按内置规则解析成 JS 原生类型。
controls: { // 全局返回字符串 decodeStrategy: "string", decoders: { // 但布尔字段仍然走自定义解码器 bool: (value: string) => ({ value: value === "t", type: "boolean" }), }, }

这条规则在query/decode.tsdecode函数中有清晰体现:先查自定义解码器,再看全局策略,最后才走内置解析。

实战案例:一次配置,格式化 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)); }, }, }, });

同样的解码规则在ClientPoolTransaction中都能使用,一套配置覆盖所有查询路径,维护成本极低。官方测试里还有更多组合玩法,可以参考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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/20 19:23:00

一套框架跑通五大平台:社交媒体数据采集的完整实战指南

一套框架跑通五大平台:社交媒体数据采集的完整实战指南 【免费下载链接】MediaCrawler-new 项目地址: https://gitcode.com/GitHub_Trending/me/MediaCrawler-new 做竞品调研的小周,曾为一组小红书笔记数据熬了三个通宵——手动复制、截图归档&a…

作者头像 李华
网站建设 2026/8/20 19:20:57

划词翻译工具深度测评:pot-desktop 跨平台翻译与截图OCR完整指南

划词翻译工具深度测评:pot-desktop 跨平台翻译与截图OCR完整指南 【免费下载链接】pot-desktop 🌈一个跨平台的划词翻译和OCR软件 | A cross-platform software for text translation and recognize. 项目地址: https://gitcode.com/pot-app/pot-deskt…

作者头像 李华
网站建设 2026/8/20 19:20:14

烟台洗衣机维修服务指南|滚筒、波轮、洗烘一体机故障检修|欧米到家

核心导读烟台地区洗衣机出现不启动、不进水、不排水、不脱水、中途停机、运行异响、机身抖动、滚筒不转、门锁无法开启、边进水边排水、洗烘效果差、故障代码报错等各类故障,均可联系欧米到家预约上门检测维修服务。欧米到家面向烟台家庭、出租房、公寓、宿舍、酒店…

作者头像 李华