Я пытаюсь вставить связанные данные в транзакцию pg-promise. Транзакция успешно вставляет все данные правильно, но выдает предупреждение UnhandledPromiseRejectionWarning: Error: Querying against a released or lost connection.
.
Код, который вызывает это, был изначально:
const item = {
batch: { batch_number: 1 },
ingredients: [
{ amount: '12', unit: 'kg' },
{ amount: '4', unit: 'L' }
],
}
return await db.tx(async t => {
const batchQueryString = pgp.helpers.insert(item.batch, null, 'ionomer_batch')
const batchQuery = await t.one(batchQueryString + ' RETURNING ionomer_batch_id')
item.ingredients.forEach(async ingredient => {
const ingredientQueryString = pgp.helpers.insert(ingredient, null, 'ingredient')
const ingredientQuery = await t.one(ingredientQueryString + ' RETURNING ingredient_id')
await t.none(
`INSERT INTO ionomer_batch_step(ionomer_batch_id, ingredient_id)
VALUES(${batchQuery.ionomer_batch_id}, ${ingredientQuery.ingredient_id})`
)
})
return batchQuery
}).then(data => {
return {success: true, response: data}
}).catch(error => {
return {success: false, response: error}
})
Я заставил его работать без предупреждения, выполнив
return await db.tx(async t => {
const batchQueryString = pgp.helpers.insert(item.batch, null, 'ionomer_batch')
const batchQuery = await t.one(batchQueryString + ' RETURNING ionomer_batch_id')
const ingredientQueries = []
// this can't be async
item.ingredients.forEach(ingredient => {
const ingredientQueryString = pgp.helpers.insert(ingredient, null, 'ingredient')
const ingredientQuery = t.one(ingredientQueryString + ' RETURNING ingredient_id')
ingredientQueries.push(ingredientQuery)
})
const resolvedIngredientQueries = await t.batch(ingredientQueries)
resolvedIngredientQueries.forEach(async ingredientQuery => {
await t.none(
`INSERT INTO ionomer_batch_step(ionomer_batch_id, ingredient_id)
VALUES(${batchQuery.ionomer_batch_id}, ${ingredientQuery.ingredient_id})`
)
})
return batchQuery
}).then(data => {
return {success: true, response: data}
}).catch(error => {
return {success: false, response: error}
})
но теперь мне приходится выполнять цикл дважды, а не один раз, и я теряю асинхронность в первом цикле. Кажется, должен быть способ сделать что-то ближе к первой попытке, не нажимая предупреждение об освобожденных или потерянных соединениях. Я играл с цепочкой запросов, но не смог заставить это работать.
item.ingredients.forEach
, которое продолжает выполняться после закрытия транзакции. Отсюда ошибка. - person vitaly-t   schedule 14.05.2020