如何在knex.js迁移脚本中链式调用Promise完成session表创建
问题根因
你的写法问题出在.then()的传参错误:.then()需要接收一个函数作为回调,你直接传入knex.schema.raw()的执行结果,会导致这两条SQL语句在createTable操作还没完成时就提前触发,此时session表尚未创建,SQL执行失败后就看起来像没有执行。
修正方案
最小改动版本(兼容你原有写法)
只需把.then()的内容改为回调函数形式,保证执行顺序:
exports.up = function (knex) { return Promise.all([ // session表操作按顺序链式执行 knex.schema .createTable("session", function (table) { table.text("sid").notNullable().collate("default"); table.json("sess").notNullable(); table.timestamp("expire", { precision: 6 }).notNullable(); }) .then(() => knex.raw( 'ALTER TABLE "session" ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;' )) .then(() => knex.raw( 'CREATE INDEX "IDX_session_expire" ON "session" ("expire");' )), // users表操作并行执行 knex.schema.createTable("users", function (table) { //...原有逻辑 }), ]); };
更推荐的Knex原生写法(无需手写raw)
直接在表创建时通过Knex内置方法配置主键和索引,代码更简洁易维护:
exports.up = function (knex) { return Promise.all([ knex.schema.createTable("session", function (table) { table.text("sid").notNullable().collate("default").primary({ constraintName: 'session_pkey', deferrable: 'immediate' }); table.json("sess").notNullable(); table.timestamp("expire", { precision: 6 }).notNullable().index('IDX_session_expire'); }), knex.schema.createTable("users", function (table) { //...原有逻辑 }), ]); };
async/await 易读版本
如果不要求session和users表操作并行,用async/await写法逻辑更清晰,不易出错:
exports.up = async function (knex) { // 按顺序执行session表相关操作 await knex.schema.createTable("session", function (table) { table.text("sid").notNullable().collate("default"); table.json("sess").notNullable(); table.timestamp("expire", { precision: 6 }).notNullable(); }); await knex.raw('ALTER TABLE "session" ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;'); await knex.raw('CREATE INDEX "IDX_session_expire" ON "session" ("expire");'); // 执行users表创建 await knex.schema.createTable("users", function (table) { //...原有逻辑 }); };
内容的提问来源于stack exchange,提问作者Zee
相关产品推荐
相关产品推荐

