使用knex为PostgreSQL加列并批量更新时Promise.all报错如何解决
问题根因
当前你使用的Knex版本已废弃了向up/down迁移函数自动注入Promise对象的特性,你在函数声明中定义的第二个形参Promise实际接收到的值为undefined,因此调用Promise.all()时触发了属性读取错误。
解决方案
按以下两步修改代码即可解决:
- 移除up函数的第二个
Promise入参,直接使用Node环境内置的全局Promise对象 - 补全事务提交/回滚的函数调用括号,同时返回内部的Promise链避免事务提前终止
修正后完整代码
export async function up(knex) { return knex.transaction(trx => { const riders = [ { name: 'Fabio Quartararo', card: 'rider_card_FabioQuartararo' }, // 其余24位车手数据 { name: 'Garrett Gerloff', card: 'rider_card_GarrettGerloff' }, ]; return knex.schema.table('riders', (table) => table.string('card')).transacting(trx) .then(() =>{ const queries = []; riders.forEach(rider => { const query = knex('riders') .update({ card: rider.card }) .where('name', rider.name) .transacting(trx); queries.push(query); }); // 新增return返回Promise链,补全commit和rollback的调用括号 return Promise.all(queries) .then(() => trx.commit()) .catch(() => trx.rollback()); }); }); }
可选优化
你也可以用async/await语法改写代码,逻辑更清晰不易出错:
export async function up(knex) { const trx = await knex.transaction(); try { // 新增字段 await knex.schema.table('riders', table => table.string('card')).transacting(trx); // 批量更新数据 const riders = [/* 车手数据 */]; for (const rider of riders) { await knex('riders') .update({ card: rider.card }) .where('name', rider.name) .transacting(trx); } await trx.commit(); } catch (e) { await trx.rollback(); throw e; } }
内容的提问来源于stack exchange,提问作者Seona Bellamy
相关产品推荐
相关产品推荐

