首页 > 解决方案 > 为什么 Knex 不能正确识别 Postgres 数组列?

问题描述

我有一张如下所示的表格:

create table if not exists gameTemplate00.construction (
    player          uuid                                constraint "[construction] Player foreign key"
                                                            references gameTemplate00.player(id),
    colony          uuid                                constraint "[construction] Colony foreign key"
                                                            references gameTemplate00.colony(id),
    location        text,                               -- All subcolonies at this location contribute to production
    investment      uint8   default 0                   not null,
    cost            uint8                               not null,
    history         uint8[3] default '{null,null,null}' not null,
    priority        uint2,
    allocation      allocation                          not null,
    repeat          boolean default false               not null,
    dispatch        text, -- what to do with the vessel once complete
    project         text,                               -- free form name for player, can be null
    constraint "[construction] Priority must be unique for a given subcolony" 
        unique(colony, location, priority)
);

当我查询它并从 Knex 获取结果时:

            db('construction')
                .withSchema('gametemplate00')
                .where('colony', payload.colony)
                .where('location', payload.location)
            .then((constructionListResult: any) => {
                ws.send(JSON.stringify(constructionListResult));
                console.log(constructionListResult);
            })

它返回这个:

 {
    player: '5f43f33b-dba6-43ca-bc0c-0516e5d29968',
    investment: '0',
    cost: '1000',
    history: '{NULL,NULL,NULL}',
    priority: '4',
    allocation: { kind: 'percent', amount: 0.35 },
    repeat: false,
    dispatch: null,
    project: 'whenever'
  }

分配是一个 jsonb 域,它正确地识别它并为其构建 json 对象。但是该数组很无聊并显示为字符串。

这是因为我的 Knex 配置错误,还是它根本无法识别 postgresql 数组列?这对我来说是问题最少的例子,但在其他人身上,不得不自己解析这些内容将变得非常痛苦。

标签: arrayspostgresqlknex.js

解决方案


这与它是一组自定义类型(来自 pguint postgres 扩展)有关。虽然过去其他人在使用数组时遇到了麻烦,但在这一点上已经处理了多年,并且看起来它应该开箱即用(对于内置类型)。

一个类似的问题揭示了。

Knex 已经在使用另一个名为 pg-types 的库。如果我在我的代码中包含它,我可以强制它将无符号整数视为正确的整数:

import * as pg from 'pg';

const newTypes = {
    INT1:     16522,
    UINT1:    16532,
    UINT2:    16542,
    UINT4:    16552,
    UINT8:    16562,
}

// add statements like below for each of the custom types

pg.types.setTypeParser(newTypes.UINT8, (value: string) => {
    return parseInt(value);
});

数据库中还有用于每种自定义类型的数组的 oid,可以通过以下方式找到:

SELECT oid, typname FROM pg_catalog.pg_type where typname like '_uint%';

但我不清楚如何将它们实际解析为适当的数组。如果/当我弄清楚时,我会更新答案。


推荐阅读