Node-Postgres/Knex 在 JS 中返回 CITEXT[] 作为字符串,而不是字符串数组

Posted

技术标签:

【中文标题】Node-Postgres/Knex 在 JS 中返回 CITEXT[] 作为字符串,而不是字符串数组【英文标题】:Node-Postgres/Knex returning CITEXT[] as a string in JS, instead of an array of strings 【发布时间】:2021-02-11 11:28:20 【问题描述】:

我正在使用Knex,它本身使用包"pg" (aka "node-postgres").

如果您从具有TEXT[] 列的表中选择一些行,那么一切都很好……在 JS 中,您会得到一个字符串数组。

但是,如果您使用的是 CITEXT[] 列,那么您只需在 JS 中返回一个字符串,例如:

"First-element,Second-element"

通常,当您想指示 pg 包如何返回特定的 postgres 类型时,您可以执行以下操作:

import types from 'pg';
types.setTypeParser(types.builtins.TIMESTAMPTZ, 'text');
types.setTypeParser(types.builtins.TIMESTAMP, 'text');
types.setTypeParser(types.builtins.DATE, 'text');
types.setTypeParser(types.builtins.TIME, 'text');
types.setTypeParser(types.builtins.TIMETZ, 'text');

types.builtins.* 常量的值是 postgres 中已知内置类型的硬编码 OID 编号。这些 OID 编号在所有 postgres 安装中都是相同的。

但是由于CITEXT[] 是一个扩展,CITEXT + CITEXT[] 类型的 OID 编号在每台服务器上都会有所不同,例如使用以下 SQL 查询:

SELECT typname, oid, typarray FROM pg_type WHERE typname like '%citext%';

在我的开发服务器上,我得到:

typname|oid  |typarray|
-------|-----|--------|
citext |17459|17464   |
_citext|17464|0       |

但在我的生产服务器上,我得到:

typname|oid  |typarray|
-------|-----|--------|
citext |18618|18623   |
_citext|18623|0       |

我该如何解决这个问题?

我真的不想做的一些 hacky 选项是:

    找出我所有服务器的所有不同 OID 值并将它们硬编码到其中 - 非常 hacky,真的不想这样做。 专门为手动将字符串转换为数组的每个表/列编写代码 - 也很老套和重复 当节点进程初始化时,获取服务器的 OID 值,然后使用该动态值调用 types.setTypeParser() 函数 - 也不是很好

如果没有这些 hacky 解决方案,我该如何解决所有表格/列的问题?

【问题讨论】:

【参考方案1】:

我不相信有任何方法可以在不查询数据库的情况下做到这一点。

我可能会在启动节点应用程序之前查询正确的 OID 号并将其存储到环境变量中,然后使用 process.env 中的值初始化 pg 类型。

这也有点 hacky,但至少 hack 大部分是封装在应用程序代码之外的。

【讨论】:

以上是关于Node-Postgres/Knex 在 JS 中返回 CITEXT[] 作为字符串,而不是字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

angular7中引入外部js文件

怎么在html文件中调用js文件

如何在js文件中调用另一个js中的方法(详细请进)

请教如何在一个js文件中调用另外一个js文件的变量

如何在html中调用js代码

如何在js文件中动态加载另一个js文件?