Knex迁移失败,出现错误:查询为空。

6
我将 knex 从0.21版本更新到了0.95版本,按照迁移指南进行了操作。现在在CI执行 npx knex migrate:latest 命令时出现了错误。
migration file "20191104160706_migrate-appsflyer_customers.js" failed
migration failed with error: The query is empty
    at createQueryBuilder (/home/circleci/backend/node_modules/knex/lib/knex-builder/make-knex.js:313:26)

但迁移文件包含了查询语句

async function up (knex) {
  // language=Postgres
  const { rows } = await knex.raw(`
    SELECT * FROM appsflyer_customer;
  `)
  const mappedRows = rows.map(row => ({
    user_id: row.user_id,
    advertising_id_type: 'appsflyer',
    advertising_id: row.appsflyer_device_id
  }))
  await knex('device_advertising_association')
    .insert(mappedRows)
}
async function down (knex) {
  await knex.raw(`
    DELETE FROM device_advertising_association WHERE user_id NOTNULL;
  `)
}
module.exports = {
  up, down
}

任何帮助都将不胜感激,因为我在处理错误信息时一无所获。
2个回答

13

我一直在遇到这个错误,自从 Knex 0.95 引入了一个新功能 https://github.com/knex/knex/pull/4289 ,如果传递一个空数组给 insert ,它将抛出一个之前不存在的错误。

既然我们没有使用那个表格,它就是空的,所以上面的迁移正在尝试插入一个空数组,而这在 CI 上引发了错误,所以我只是用 try-catch 块处理了 Exception,并解决了这个问题。

因此,作为一个提示,请仔细查看更改日志。


0

我正在使用node.js 14和knex 0.95。

这里有一个专门针对knex(...).insert([])的修复方法,但请谨慎使用,如下所述。尽管函数名为monkeyPatchKnexForMinor21ToMinor95Migration,但它只修补了1个问题,没有其他作用。

待办事项:这会破坏像const r = await knex('my_table').insert([]).returning('*');这样的用法。这将抛出类似于TypeError: knex('my_table').insert(...).returning is not a function的错误。

function monkeyPatchKnexForMinor21ToMinor95Migration() {
  const Builder = require('knex/lib/query/querybuilder');
  const QueryInterface = require('knex/lib/query/method-constants');

  Builder.prototype.insert = new Proxy(Builder.prototype.insert, {
    apply: function (target, thisArg, args) {
      const attemptedInsertWithEmptyArray = args?.[0]?.length === 0
        && args?.[0] instanceof Array;

      if (attemptedInsertWithEmptyArray) {
        return target.call(thisArg, ...args).catch(error => {
          if (error.message === 'The query is empty') {
            // very loose shallow mock of knex Result type based on what 
            // knex@0.21 would return for insertion of empty array                
            return {
              command: null,
              rowCount: null,
              oid: null,
              rows: [],
              fields: [],
              RowCtor: null,
              rowAsArray: false,
            };
          }

          throw error;
        });
      }

      return target.call(thisArg, ...args);
    }
  });

  const knex = require('knex');
  knex.QueryBuilder = {
    extend: function (methodName, fn) {
      Builder.extend(methodName, fn);
      QueryInterface.push(methodName);
    }
  };
  
  return knex;
}

使用方法:无论在何处导入knex,您都应该调用此函数。另一种选择是尝试猴子补丁require('knex')调用本身,并在初始化应用程序和客户端创建以及导入依赖项之前执行该操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接