使用 sequelize.transaction 时使用外键创建记录失败
Creating record with foreign key fails when using sequelize.transaction
我有一个简单的 Message
属于 User
,Message
属于 Chat
架构。
models.Chat.hasMany(models.Message);
models.Message.belongsTo(models.Chat);
models.User.hasMany(models.Message);
models.Message.belongsTo(models.User);
当我创建新的 Message
记录时(在创建 User
和 Chat
记录之后),以下工作正常:
const message = await models.Message.create({
UserId: user_id,
ChatId: chat_id,
content: content,
});
然而,以下包含托管事务的操作失败了:
const message = await sequelize.transaction(
async (transaction: Transaction) => {
// First create the message.
const ret = await models.Message.create(
{
UserId: user_id,
ChatId: chat_id,
content: content,
},
{ transaction }
);
return ret;
}
);
错误:
{
name: 'SequelizeForeignKeyConstraintError',
parent: error: insert or update on table "Messages" violates foreign key constraint "Messages_ChatId_fkey"
at Parser.parseErrorMessage (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:357:11)
at Parser.handlePacket (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:186:21)
at Parser.parse (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:101:30)
at Socket.<anonymous> (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (node:events:327:20)
at addChunk (node:internal/streams/readable:304:12)
at readableAddChunk (node:internal/streams/readable:279:9)
at Socket.Readable.push (node:internal/streams/readable:218:10)
at TCP.onStreamRead (node:internal/stream_base_commons:192:23) {
length: 286,
severity: 'ERROR',
code: '23503',
detail: 'Key (ChatId)=(900e18b1-1a62-45b7-bd74-3cecc8a80de8) is not present in table "Chats".',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'Messages',
column: undefined,
dataType: undefined,
constraint: 'Messages_ChatId_fkey',
file: 'ri_triggers.c',
line: '2463',
routine: 'ri_ReportViolation',
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
]
},
original: error: insert or update on table "Messages" violates foreign key constraint "Messages_ChatId_fkey"
at Parser.parseErrorMessage (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:357:11)
at Parser.handlePacket (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:186:21)
at Parser.parse (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:101:30)
at Socket.<anonymous> (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (node:events:327:20)
at addChunk (node:internal/streams/readable:304:12)
at readableAddChunk (node:internal/streams/readable:279:9)
at Socket.Readable.push (node:internal/streams/readable:218:10)
at TCP.onStreamRead (node:internal/stream_base_commons:192:23) {
length: 286,
severity: 'ERROR',
code: '23503',
detail: 'Key (ChatId)=(900e18b1-1a62-45b7-bd74-3cecc8a80de8) is not present in table "Chats".',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'Messages',
column: undefined,
dataType: undefined,
constraint: 'Messages_ChatId_fkey',
file: 'ri_triggers.c',
line: '2463',
routine: 'ri_ReportViolation',
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
]
},
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
],
fields: null,
table: 'Messages',
value: undefined,
index: 'Messages_ChatId_fkey',
reltype: undefined
}
我通过在交易之前以及交易中的 await models.Message.create
之前查询 models.Chat.findAll
确实验证了具有所提供 ID 的聊天确实存在。
所以这与我在测试中使用的 sequelize
实例与我的 Express 应用中实际使用的实例有关。
我正在导入我为我的 Express 应用程序初始化的全局 sequelize
实例,但在我的测试中使用了不同的 sequelize
实例。
我有一个简单的 Message
属于 User
,Message
属于 Chat
架构。
models.Chat.hasMany(models.Message);
models.Message.belongsTo(models.Chat);
models.User.hasMany(models.Message);
models.Message.belongsTo(models.User);
当我创建新的 Message
记录时(在创建 User
和 Chat
记录之后),以下工作正常:
const message = await models.Message.create({
UserId: user_id,
ChatId: chat_id,
content: content,
});
然而,以下包含托管事务的操作失败了:
const message = await sequelize.transaction(
async (transaction: Transaction) => {
// First create the message.
const ret = await models.Message.create(
{
UserId: user_id,
ChatId: chat_id,
content: content,
},
{ transaction }
);
return ret;
}
);
错误:
{
name: 'SequelizeForeignKeyConstraintError',
parent: error: insert or update on table "Messages" violates foreign key constraint "Messages_ChatId_fkey"
at Parser.parseErrorMessage (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:357:11)
at Parser.handlePacket (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:186:21)
at Parser.parse (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:101:30)
at Socket.<anonymous> (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (node:events:327:20)
at addChunk (node:internal/streams/readable:304:12)
at readableAddChunk (node:internal/streams/readable:279:9)
at Socket.Readable.push (node:internal/streams/readable:218:10)
at TCP.onStreamRead (node:internal/stream_base_commons:192:23) {
length: 286,
severity: 'ERROR',
code: '23503',
detail: 'Key (ChatId)=(900e18b1-1a62-45b7-bd74-3cecc8a80de8) is not present in table "Chats".',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'Messages',
column: undefined,
dataType: undefined,
constraint: 'Messages_ChatId_fkey',
file: 'ri_triggers.c',
line: '2463',
routine: 'ri_ReportViolation',
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
]
},
original: error: insert or update on table "Messages" violates foreign key constraint "Messages_ChatId_fkey"
at Parser.parseErrorMessage (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:357:11)
at Parser.handlePacket (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:186:21)
at Parser.parse (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/parser.ts:101:30)
at Socket.<anonymous> (/mnt/ubuntu/home/richardwu/code/topspin-apollo-backend/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (node:events:327:20)
at addChunk (node:internal/streams/readable:304:12)
at readableAddChunk (node:internal/streams/readable:279:9)
at Socket.Readable.push (node:internal/streams/readable:218:10)
at TCP.onStreamRead (node:internal/stream_base_commons:192:23) {
length: 286,
severity: 'ERROR',
code: '23503',
detail: 'Key (ChatId)=(900e18b1-1a62-45b7-bd74-3cecc8a80de8) is not present in table "Chats".',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'Messages',
column: undefined,
dataType: undefined,
constraint: 'Messages_ChatId_fkey',
file: 'ri_triggers.c',
line: '2463',
routine: 'ri_ReportViolation',
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
]
},
sql: 'INSERT INTO "Messages" ("id","content","createdAt","updatedAt","ChatId","UserId") VALUES (,,,,,) RETURNING "id","content","createdAt","updatedAt","ChatId","UserId";',
parameters: [
'392749a4-267e-4e8f-b58d-93ad84004ab3',
'hello',
'2021-02-27 21:10:41.306 +00:00',
'2021-02-27 21:10:41.306 +00:00',
'900e18b1-1a62-45b7-bd74-3cecc8a80de8',
'843095e7-0ee1-4db5-bfcf-d14d5e595019'
],
fields: null,
table: 'Messages',
value: undefined,
index: 'Messages_ChatId_fkey',
reltype: undefined
}
我通过在交易之前以及交易中的 await models.Message.create
之前查询 models.Chat.findAll
确实验证了具有所提供 ID 的聊天确实存在。
所以这与我在测试中使用的 sequelize
实例与我的 Express 应用中实际使用的实例有关。
我正在导入我为我的 Express 应用程序初始化的全局 sequelize
实例,但在我的测试中使用了不同的 sequelize
实例。