1

在按照cockroachdb 示例使用 node.js 的sequelize orm构建应用程序时,我对其进行了扩展以添加模型之间的关联。主键是 INT,通过 unique_rowid() 自动递增。根据您的文档,这是您的SERIAL实现。

同步我的模型后,我尝试使用以下代码创建记录:

models.sequelize.sync({ force: true })
  .then(function () {
    return models.Customer.create({
      name: "Sample Customer"
    })
  })
  .then(function (result) {
    const id = parseInt(result.dataValues.id, 10)
    return models.Order.bulkCreate([
      { subtotal: 100.00, customer_id: id },
      { subtotal: 200.00, customer_id: id }
    ])
  })

当它运行时,我得到“ error: foreign key violation: value [255737842446434300] not found in customers@primary [id]

我意识到我的parseInt似乎没有获取从客户创建返回的字符串 id 所需的精度,但我不知道如何实现这一点。

4

1 回答 1

2

更新,2017 年 7 月 6 日。

sequelize-cockroachdb的最新版本v1.0.2 教导 Sequelize 将数字上下文中使用的字符串强制转换为 CockroachDB 整数。只需不要调用parseIntresult.dataValues.id,它应该可以按您的预期工作!

models.sequelize.sync({ force: true })
  .then(function () {
    return models.Customer.create({
      name: "Sample Customer"
    })
  })
  .then(function (result) {
    return models.Order.bulkCreate([
      { subtotal: 100.00, customer_id: result.dataValues.id },
      { subtotal: 200.00, customer_id: result.dataValues.id }
    ])
  })

正如您所发现的,问题是由 生成的 ID(unique_rowid()如 255737842446434300)太大而无法放入JavaScript Number中,它只能精确表示不超过 2 53 - 1 的整数。解决此问题的通常方法是使用而是字符串。也就是说,您可以简单地忽略对的调用parseInt{ ..., customer_id: "255737842446434300"}直接传递给Order.bulkCreate.

不幸的是,Sequelize 随后会生成如下所示的 SQL 语句:

INSERT INTO orders (customer_id) VALUES ('255737842446434300');

PostgreSQL 很乐意将该字符串文字转换为int8,但 CockroachDB 会抱怨在int8预期使用 an 的地方使用字符串文字。我已经打开 PR 来在CockroachDB 端Sequelize 适配器端解决这个问题,但都还没有登陆。但是,我们几乎肯定会为 v1.1 提供解决方案!


Sequelize.BLOB同时——特别是如果你想要一个与 CockroachDB v1.0 兼容的解决方案——你可以通过使用 UUID 主键和类型来解决这个问题。

于 2017-06-24T17:40:49.910 回答