我有一个快速应用程序,并使用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",
},
]
1条答案
按热度按时间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,…:-(((