在Node.js中使用SERIAL的外键违规

在继续使用cockroachdb示例为node.js使用sequelize orm构build应用程序时,我扩展了它以在模型之间添加关联。 主键是INT,通过unique_rowid()自动递增。 根据你的文档,这是你的SERIAL的实现。

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

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似乎没有所需的精度,以从客户创build返回的stringID,但我不知道如何做到这一点。

2017年7月6日更新。

sequelize-cockroachdb ,v1.0.2的最新版本教导Sequelize将数字上下文中使用的string强制转换为CockroachDB整数。 不要在result.dataValues.id上调用parseInt ,它应该像你期望的那样工作!

 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 } ]) }) 

这个问题,正如你发现的那样,由unique_rowid()生成的unique_rowid()如255737842446434300)太大,不适合JavaScript Number ,它只能够精确地表示整数达到2 53 – 1。通常解决这个问题的方法是用string代替。 也就是说,您可以简单地将调用parseInt并直接将{ ..., customer_id: "255737842446434300"}传递给Order.bulkCreate

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

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

PostgreSQL会很高兴地把这个string转换成一个int8 ,但是CockroachDB会抱怨使用一个int8的string。 我已经打开PR来解决这个CockroachDB端或Sequelize适配器端 ,但都没有降落。 然而,我们几乎肯定会有v1.1的解决scheme!


与此同时,特别是如果您想要与CockroachDB v1.0兼容的解决scheme,则可以使用Sequelize.BLOBtypes的UUID主键来解决此问题。

Interesting Posts