将函数传递给 Knex select 方法会中断查询

Passing function to Knex select method breaks querying

代码:

const knex = require("../../db/knex");

module.exports = (request, response) => {
  knex
    .select((builder) => {
      const select = request.query.select;

      if (select) {
        if (select.constructor === String) {
          builder.select(select);
        } else if (select.constructor === Array) {
          builder.select(...select);
        }
      } else {
        /* Anything that goes here or inside this function, breaks it. */
      }
    })
    .from("tags")
    .where((builder) => {
      const filter = request.query.filter;

      if (filter) {
        if (filter.constructor === Object) {
          builder.where(filter);
        } else if (filter.constructor === Array) {
          builder.where(...filter);
        }
      } else {
        builder.clear("where");
      }
    })
    .then((result) => response.json(result))
    .catch((error) => response.json({ ...error, message: error.stack }));
};

完整错误:

{
    "length": 180,
    "name": "error",
    "severity": "ERROR",
    "code": "42601",
    "position": "16",
    "file": "d:\pginstaller_13.auto\postgres.windows-x64\src\backend\parser\parse_target.c",
    "line": "1296",
    "routine": "ExpandAllTables",
    "message": "error: select (select *) from \"tags\" - SELECT * with no tables specified is not valid\n    at Parser.parseErrorMessage (C:\Users\Lucas\Desktop\Repositories\projeto-integrador-dh-g1\node_modules\pg-protocol\dist\parser.js:278:15)\n    at Parser.handlePacket (C:\Users\Lucas\Desktop\Repositories\projeto-integrador-dh-g1\node_modules\pg-protocol\dist\parser.js:126:29)\n    at Parser.parse (C:\Users\Lucas\Desktop\Repositories\projeto-integrador-dh-g1\node_modules\pg-protocol\dist\parser.js:39:38)\n    at Socket.<anonymous> (C:\Users\Lucas\Desktop\Repositories\projeto-integrador-dh-g1\node_modules\pg-protocol\dist\index.js:10:42)\n    at Socket.emit (events.js:315:20)\n    at addChunk (internal/streams/readable.js:309:12)\n    at readableAddChunk (internal/streams/readable.js:284:9)\n    at Socket.Readable.push (internal/streams/readable.js:223:10)\n    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)"
}

我使用 Express 管理节点服务器,使用 Knex 管理数据库。在这条路线中,如果我从 select 中删除函数,一切正常。什么都试过了,我不明白为什么不工作。任何人都可以帮助我理解它为什么会崩溃吗?

Knex 中的 select() 方法从您的 table 中获取列名到 select。我不认为你可以像你想做的那样正确地传递一个函数。您可以像以前那样在 .where() 中执行此操作。但我首先要从 select().

中删除所有 if/else 逻辑

如果您需要转换接收到的数据,请在构建查询之前执行此操作。或许还有其他查询构建方法可以帮助您获得所需的结果。

如评论中所述,Knex 将正在执行的操作视为子查询。我发现处理这些情况的正确方法是使用 modify.

我现在遇到了这样的事情:

const knex = require("../../db/knex");

module.exports = (request, response, next) => {
  knex
    .from("tags")
    .modify((builder) => {
      const filter = request.query.filter;
      const select = request.query.select;
      const order = request.query.order;
      const id = request.params.id;

      if (select) {
        if (select.constructor === String || select.constructor === Object) {
          builder.select(select);
        } else if (select.constructor === Array) {
          builder.select(...select);
        }
      }

      if (id) {
        builder.where({ id: id }).first();
      } else if (filter) {
        if (filter.constructor === Object) {
          builder.where(filter);
        } else if (filter.constructor === Array) {
          builder.where(...filter);
        }
      }

      if (!id) {
        if (order) {
          if (order.constructor === String) {
            builder.orderBy(order);
          } else if (order.constructor === Array) {
            builder.orderBy(...order);
          }
        }
      }
    })
    .then((result) => response.json(result))
    .catch((error) => next(error));
};