Sequelize将整数作为字符串返回

15

我正在使用nodejs v4和sequelize,我有一个像这样的模型:

var Device = sequelize.define('Device', {
id: {
  type: DataTypes.BIGINT,
  primaryKey: true,
  autoIncrement: true
},
tenantId: {
  type: DataTypes.BIGINT,
  allowNull: false
},
token: {
  type: DataTypes.STRING,
  allowNull: false
}
}, {
 tableName: 'devices'
});
当我通过 ID 选择设备时,ID 的类型是字符串,例如:
Device.findById(9).then( function(result) {
  console.log(result.toJSON().id + 10);
});

输出结果将为910而不是19,因此我查看了JSON并发现了以下内容:

{
  id: "9"
  tenantId: "123"
  token: "adsadsdsa"
}

发现设备中的id是一个字符串,但我定义它为一个数字...

不应该是 { "id": 9 } 吗?

如何使用我之前定义的类型来选择设备?

6个回答

11

BIGINT最大值为2^63-1,JavaScript可以安全地表示最高达2^53的值。为了保险起见,库会将这些数字返回为字符串。

如果你想得到数字而不是字符串,可以使用这个库https://github.com/mirek/node-pg-safe-numbers来解决这个问题。


7

我在sequelize存储库中找到了解决此问题的方法。

https://github.com/sequelize/sequelize/issues/4523

用于sequelize的pg模块将bigint返回为字符串,因为不能保证bigints适合js数字。因此,我更改了我的模型使用integer(DataTypes.INTEGER)。


4
如果我说错了请纠正我,但我认为你还需要更改你的数据库架构才能使其工作。在我的例子中(使用PostgreSQL),这并没有修复任何问题。 - backdesk

2

在我看来,更加流畅的解决方案是将int类型强制转换为int,而不是字符串。请查看这个问题和评论


但是如果字符串中的整数大于JS中最大的安全整数,结果会是什么? - Oleksandr Grin

0
尝试将这行代码放在逻辑代码之前对我有用,这会强制将int8解析为int,而不是字符串:
require("pg").defaults.parseInt8 = true;

...

try {
    const list = await Posts.findAll();
    console.log(JSON.stringify(list));
} catch (e) {
    console.log(e.message);
}


这对我的使用情况有效,但值得注意的是,如果您有大于2^53的数字,则可能会返回不正确的值。 - Scott Stevens
抱歉,我不小心给你的回答提了一个编辑请求。 - Ashu Sahu

0

我在我的Sequelize模型上所做的是在getter函数中应用parseFloat。

这是一个示例TypeScript代码。

@Column({
    type: DataType.DECIMAL(9, 2),
    get() {
        return parseFloat(this.getDataValue('amount') as string);
    },
})
amount?: number;


使用这个,你可以运用逻辑来处理小型和大型整数数据类型。

-3
默认情况下,Sequelize会尝试格式化您的结果。您可以设置raw: true来获取原始数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接