英文:
Node.js Connection terminated before query is finished
问题
新手使用node.js。
我在一个托管有PostgreSQL
数据库的Windows服务器上设置了一个Node/express服务器。
我的目标是通过一个HTML表单,将用户在自己计算机上选择的csv文件中的数据插入到数据库中。
以下是用户提交表单后执行的js文件部分:
app.post('/envoi', upload.single("fichiercsv"), async(req, res) => {
let newClient
try {
const { identifiant, motdepasse } = req.body
const clientConfigModifie = {
...clientConfigDefaut,
user: identifiant,
password: ''
}
newClient = new Client(clientConfigModifie)
await newClient.connect()
const rows = []
const buffer = req.file.buffer
const readableStreamFromBuffer = new stream.Readable()
readableStreamFromBuffer.push(req.file.buffer)
readableStreamFromBuffer.push(null)
await new Promise((resolve, reject) => {
fastcsv.parseStream(readableStreamFromBuffer, { headers: false })
.on('data', us => {
rows.push(us)
})
.on('end', async() => {
rows.shift()
const usTotal = rows.map(us => us.join("").split(";"))
for (const us of usTotal) {
await newClient.query("insert into activite.us (numus, gidgeo) VALUES ($1, $2)", [us[0], us[13]])
}
resolve()
})
.on("error", error => console.error(error))
})
} catch (e) {
console.log("erreur lors du traitement", e)
res.send('<h3>échec de la connexion</h3>')
} finally {
try {
newClient.end()
} catch (e) {
console.log(e)
}
}
})
- 如果我省略
finally
部分,数据将被插入到数据库中,但连接仍在运行... - 使用
finally
部分,只有第一行的us
被插入。因此,我收到以下消息:
error: Connection terminated at C:\Apache\balbla\
在这种情况下,似乎newClient.query
只运行一次,然后由于某种原因连接被终止但未结束。
我做错了什么?
英文:
Newbie with node.js.
I have set up an Node/express server on a Windows Server hosting a PostgreSQL
database.
My goal is to insert in the database the data from a csv file choosen by a user on its own computer, using a HTML form.
Here is the part of the js file executed after the user submits the form:
app.post('/envoi', upload.single("fichiercsv"), async(req, res) => {
let newClient
try {
const { identifiant, motdepasse } = req.body
const clientConfigModifie = {
...clientConfigDefaut,
user: identifiant,
password: ''
}
newClient = new Client(clientConfigModifie)
await newClient.connect()
const rows = []
const buffer = req.file.buffer
// console.log(buffer) //ok
const readableStreamFromBuffer = new stream.Readable()
readableStreamFromBuffer.push(req.file.buffer)
readableStreamFromBuffer.push(null)
await new Promise( (resolve, reject) => {
fastcsv.parseStream(readableStreamFromBuffer, { headers: false })
.on('data', us => {
rows.push(us)
})
.on('end', async() => {
rows.shift()
const usTotal = rows.map( us => us.join("").split(";"))
// console.log(us)
for (const us of usTotal) {
await newClient.query("insert into activite.us (numus, gidgeo) VALUES ($1, $2)", [us[0], us[13]])
})
resolve()
})
.on("error", error => console.error(error))
})
}
catch(e) {
console.log("erreur lors du traitement", e)
res.send(`<h3>échec de la connexion</h3>`)
}
finally {
try {
newClient.end()
}
catch(e) {
console.log(e)
}
}
})
- If I omit the
finally
part, the data are inserted in the database, but the connection is running... - With the
finally
part, only the first row ofus
is inserted. Thus, I have the message :
error: Connection terminated at C:\Apache\balbla\
In this case, it seems that newClient.query
runs one time only then for some reason the connection is terminated but not ended.
What am I doing wrong ?
EDIT : code updated after @I2yscho answer.
答案1
得分: 1
问题是你没有异步处理插入操作。这段代码不是处理这个问题的最佳方式,但它是一个可行的解决方案。我建议你使用某种形式的批量插入来进行一次查询。
.on('end', () => {
rows.shift();
const usData = rows.map(us => us.join("").split(";"));
const insertPromises = usData.map(us => {
return newClient.query("INSERT INTO activite.us (numus, gidgeo) VALUES ($1, $2)", [us[0], us[13]]);
});
Promise.all(insertPromises)
.then(() => {
resolve();
})
.catch(error => {
reject(error);
});
})
英文:
Problem is you don't handle insert operations asynchronously. This code is not a best way how to handle this, but it is working solution. I recommend you to use some sort of bulk insert in one query.
.on('end', () => {
rows.shift();
const usData = rows.map(us => us.join("").split(";"));
const insertPromises = usData.map(us => {
return newClient.query("INSERT INTO activite.us (numus, gidgeo) VALUES ($1, $2)", [us[0], us[13]]);
});
Promise.all(insertPromises)
.then(() => {
resolve();
})
.catch(error => {
reject(error);
});
})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论