You need to enable JavaScript to run this app. 如何在knex.js迁移脚本中链式调用Promise完成session表创建
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 21:15:04