英文:
Node.js Connection terminated before query is finished
问题 {#heading}
新手使用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 finallypart, the data are inserted in the database, but the connection is running...
- With the finallypart, only the first row ofusis 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}
得分: 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);
});
})
 51工具盒子
51工具盒子 
                 
                             
                         
                         
                        