当数组大小大于3时,从knex使用batchinsert时,得到未处理的承诺拒绝

6ljaweal  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(374)

我有一个快速应用程序,并使用knex作为查询字符串生成器。
当我使用batch insert预测1000+个对象的数组时,如果数组太长,我会收到一个错误(我将确切的错误粘贴到问题的后面)
如果我的testfields数组中有3个或更少的对象,那么数据会正确地插入到数据库中,任何大于3的对象都会收到错误。所以,我相信,出于某种原因,问题在于数组中元素的数量。
我通过捕获要插入的数据并对其进行硬编码来隔离问题。变量testfields用作batchinsert中的数据,可以在这个问题的底部找到。
我的数据库正在azure上托管。
我当前的节点版本是v12.18.0。
这是我的package.json

{
  "name": "expressjs",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "dev": "nodemon ./bin/www"
  },
  "dependencies": {
    "@azure/identity": "^1.0.3",
    "@azure/keyvault-keys": "^4.0.4",
    "axios": "^0.19.2",
    "azure-keyvault": "^3.0.5",
    "cookie-parser": "^1.4.5",
    "cors": "^2.8.5",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "express-jwt": "^5.3.3",
    "express-jwt-authz": "^2.4.0",
    "express-ws": "^4.0.0",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "jwks-rsa": "^1.8.0",
    "knex": "^0.20.15",
    "lodash": "^4.17.15",
    "morgan": "~1.9.1",
    "ms-rest-azure": "^3.0.0",
    "mssql": "^5.1.1",
    "qs": "^6.9.4",
    "socket.io": "^2.3.0",
    "tedious": "^6.7.0",
    "ws": "^7.3.0"
  }
}

这是我的代码从快速路线和knex查询。

const isolateProblem = (res) => {
  // need to get connection string from vault
  return getKnexWithConString
    .then((knex) => {
      return knex
        .batchInsert("Tasks", testFields)
        .returning("pk_Tasks")
        .then((result) => {
          res.send("okay");
          return result;
        })
        .catch((err) => {
          res.send("not okay 1");
          console.log("err", err);
        });
    })
    .catch((err) => {
      res.send("not okay");
      console.log("err2:", err);
    });
};

router.get("/", async (req, res) => {
  const data = await isolateProblem(res);
  console.log("data", data);
});

如果我的数组大于3个对象,这就是我收到的错误。这似乎是源于事务的未处理的承诺警告。js:45:38。我不知道我是怎么做的。
"(node:805)未处理的PromisejectionWarning:typeerror:无法分配给对象“transactionerror:请求只能在loggedin状态下发出,而不是在…node\u modules/knex/lib/diagnols/mssql/transaction.js:45:38处的最终状态下发出(node:805)未处理的PromisejectionWarning:未处理的承诺拒绝。
此错误可能是由于在没有catch块的异步函数内部引发的,也可能是由于拒绝了未使用.catch()处理的承诺。要在未处理的承诺拒绝时终止节点进程,请使用cli标志 --unhandled-rejections=strict (见https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (拒绝id:1)(node:805)[dep0018]弃用警告:未处理的承诺拒绝已弃用。将来,未处理的承诺拒绝将使用非零退出代码终止node.js进程。”
下面的变量表示要插入的对象的形状。请注意,出于隐私原因,我已经隐藏了字段名和值。
另外,这个数组有4个元素,所以它会收到上面的错误。如果我删除这些元素中的任何一个,使数组长度为3,那么插入数据就没有问题了。
谢谢你的帮助!

const testFields = [
  {
    SqlField1: "00000",
    SqlField2: "",
    SqlField3: null,
    SqlField4: null,
    SqlField5: "UUID",
    SqlField6: null,
    SqlField7: "",
    SqlField8: "",
    SqlField9: "UUID",
    SqlField10: "Name",
    SqlField11: "",
    SqlField12: "",
    SqlField13: "",
    SqlField14: "",
    SqlField15: true,
    SqlField16: true,
    SqlField17: "UUID",
    SqlField18: "status",
    SqlField19: null,
    SqlField20: null,
    SqlField21: "###",
    SqlField22: "###",
    SqlField23: "###",
    SqlField24: null,
    SqlField25: false,
    SqlField26: null,
    SqlField27: new Date(Date.now()),
    SqlField28: new Date(Date.now()),
    SqlField29: "userName",
    SqlField30: "userName",
  },
  {
    SqlField1: "00000",
    SqlField2: "",
    SqlField3: null,
    SqlField4: null,
    SqlField5: "UUID",
    SqlField6: null,
    SqlField7: "",
    SqlField8: "",
    SqlField9: "UUID",
    SqlField10: "Name",
    SqlField11: "",
    SqlField12: "",
    SqlField13: "",
    SqlField14: "",
    SqlField15: true,
    SqlField16: true,
    SqlField17: "UUID",
    SqlField18: "status",
    SqlField19: null,
    SqlField20: null,
    SqlField21: "###",
    SqlField22: "###",
    SqlField23: "###",
    SqlField24: null,
    SqlField25: false,
    SqlField26: null,
    SqlField27: new Date(Date.now()),
    SqlField28: new Date(Date.now()),
    SqlField29: "userName",
    SqlField30: "userName",
  },
  {
    SqlField1: "00000",
    SqlField2: "",
    SqlField3: null,
    SqlField4: null,
    SqlField5: "UUID",
    SqlField6: null,
    SqlField7: "",
    SqlField8: "",
    SqlField9: "UUID",
    SqlField10: "Name",
    SqlField11: "",
    SqlField12: "",
    SqlField13: "",
    SqlField14: "",
    SqlField15: true,
    SqlField16: true,
    SqlField17: "UUID",
    SqlField18: "status",
    SqlField19: null,
    SqlField20: null,
    SqlField21: "###",
    SqlField22: "###",
    SqlField23: "###",
    SqlField24: null,
    SqlField25: false,
    SqlField26: null,
    SqlField27: new Date(Date.now()),
    SqlField28: new Date(Date.now()),
    SqlField29: "userName",
    SqlField30: "userName",
  },
  {
    SqlField1: "00000",
    SqlField2: "",
    SqlField3: null,
    SqlField4: null,
    SqlField5: "UUID",
    SqlField6: null,
    SqlField7: "",
    SqlField8: "",
    SqlField9: "UUID",
    SqlField10: "Name",
    SqlField11: "",
    SqlField12: "",
    SqlField13: "",
    SqlField14: "",
    SqlField15: true,
    SqlField16: true,
    SqlField17: "UUID",
    SqlField18: "status",
    SqlField19: null,
    SqlField20: null,
    SqlField21: "###",
    SqlField22: "###",
    SqlField23: "###",
    SqlField24: null,
    SqlField25: false,
    SqlField26: null,
    SqlField27: new Date(Date.now()),
    SqlField28: new Date(Date.now()),
    SqlField29: "userName",
    SqlField30: "userName",
  },
]
goucqfw6

goucqfw61#

遇到同样的问题,我做了一些常规测试,发现行为取决于batchinsert中使用的参数的数量和大小。
大小为64的数据数组a=[{“a”:1,“b”:“1”},…]正确插入,没有错误。添加一个元素{“a”:1,“b”:“1”}会导致错误。
可能基础prepared语句的128个参数是最终导致失败的根本原因的限制?
“knex”:“^0.20.11”
“mssql”:“^5.1.1”
节点v12.14.1
我要么
将我的数据切片到可以用batchinsert处理的Chunck中:-(
直接移动到单例插入:-((
忘掉knex/nodejs,回到java,…:-(((

相关问题