【发布时间】:2022-01-20 12:41:33
【问题描述】:
我正在尝试从一个数组在数据库中进行多次插入,但是...我在断开与数据库的连接和断开连接时遇到问题
例如,在这段代码中,我只插入了第一个元素,然后我得到了一个错误,因为对数据库的访问已经断开。
async function saveData(destinations){
let ddbb = new PostgresqlDDBB();
ddbb.connect();
await destinations.forEach(async (country, index) => {
let params = [country.countryName, country.countryCode, country.urlProperties];
let id = await ddbb.insertData(2, params);
destinations[index].id = id;
});
ddbb.disconnect()
}
对象 PostgresqlDDBB 有这样的代码:
import {Result} from "../../com/result";
import {clientPG} from "./pg_connection";
import {selectQuery} from "../queries/pg_queries";
class PostgresqlDDBB{
constructor(){
this.query = null;
}
set query(id){
this.__query = selectQuery(id);
}
get query(){
return this.__query;
}
async connect(){
await clientPG.connect();
}
disconnect(){
clientPG.end();
}
/**
*
* @param {*} id_query ID of query to run
* @param {*} params params to pass to the query
* @returns The last id save in the database
*/
async insertData(id_query, params){
let result;
try{
let query = selectQuery(id_query);
if (params !== null)
result = await clientPG.query(query, params);
else
result = await clientPG.query(query);
return result.rows[0].id;
}catch(err){
console.log(err.stack);
}
}
}
module.exports.PostgresqlDDBB = PostgresqlDDBB;
Postgress 的客户端有这样的代码:
import {Client} from "pg";
import config from "../../config";
const clientPG = new Client({
user: config.db_postgres.user,
password: config.db_postgres.password,
database: config.db_postgres.name,
host: config.db_postgres.host,
//ssl: config.db_postgres.ssl
});
module.exports.clientPG = clientPG;
找saveData的代码我不知道为什么forEach不等待完成所有元素的插入。
如果我用 for 代替 forEach 做同样的事情并调用该函数两次:
async function saveData(destinations){
let ddbb = new PostgresqlDDBB();
await ddbb.connect();
for(let i = 0; i < destinations.length; i++){
let country = destinations[i];
let params = [country.countryName, country.countryCode, country.urlProperties];
let id = await ddbb.insertData(2, params);
}
ddbb.disconnect();
console.log("Voy a salir!!!");
};
saveData(list);
saveData(list);
第一次运行正常,但第二次出现此错误:
Voy a salir!!!
/home/josecarlos/Workspace/BlueCode/Youmalou/mapping-service/node_modules/pg/lib/client.js:94
const err = new Error('Client has already been connected. You cannot reuse a client.')
^
Error: Client has already been connected. You cannot reuse a client.
我们第二次运行该函数时,连接仍然打开。这怎么可能?
打开连接的最佳时机是什么时候?打开连接而不是关闭它是一个很好的做法,因为当对象也会被删除时,连接也会被删除?
如何打开、插入数据、关闭连接、再次打开连接、插入数据、关闭连接等?
我做错了吗?
编辑我:
如果我修改我的代码以使等待连接/断开连接。我第二次尝试运行 saveData 方法时遇到此错误。
const err = new Error('Client has already been connected. You cannot reuse a client.')
^
Error: Client has already been connected. You cannot reuse a client.
方法的代码是:
async function saveGIATAData(countries){
let ddbb = new PostgresqlDDBB();
await ddbb.connect();
for(let i = 0; i < countries.length; i++){
let country = countries[i];
let params = [country.countryName, country.countryCode, country.urlProperties];
let id = await ddbb.insertData(2, params);
}
await ddbb.disconnect();
console.log("Voy a salir!!!");
}
对象PostgresqlDDBB的代码是:
import {Result} from "../../com/result";
import {clientPG} from "./pg_connection";
import {selectQuery} from "../queries/pg_queries";
class PostgresqlDDBB{
constructor(){
this.query = null;
}
set query(id){
this.__query = selectQuery(id);
}
get query(){
return this.__query;
}
async connect(){
await clientPG.connect();
}
async disconnect(){
await clientPG.end();
}
/**
*
* @param {*} id_query ID of query to run
* @param {*} params params to pass to the query
* @returns The last id save in the database
*/
async insertData(id_query, params){
let result;
try{
let query = selectQuery(id_query);
if (params !== null)
result = await clientPG.query(query, params);
else
result = await clientPG.query(query);
return result.rows[0].id;
}catch(err){
console.log(err.stack);
}
}
}
module.exports.PostgresqlDDBB = PostgresqlDDBB;
而客户端的代码是:
import {Client} from "pg";
import config from "../../config";
const clientPG = new Client({
user: config.db_postgres.user,
password: config.db_postgres.password,
database: config.db_postgres.name,
host: config.db_postgres.host,
//ssl: config.db_postgres.ssl
});
module.exports.clientPG = clientPG;
而且,就像我之前所说的,我第二次尝试运行该方法时出现错误,告诉我客户端已经打开。
发生了什么?我不明白发生了什么。
【问题讨论】:
-
在异步函数中,应始终等待数据库连接/断开连接。
-
@JGH 感谢您的赞赏帮助,但它仍然对我不起作用:(我在原帖中添加了更多信息。
-
您确定
destinations.forEach支持异步处理程序并返回 Promise? -
@Anatoly 根据我的经验,array.forEach 不支持异步处理程序。因此,我通过 for 循环进行了更改。通过使用 for,但是,使用 for 我可以插入第一次调用该方法的所有插入,但是当我尝试打开连接时第二次尝试调用该方法时,出现错误,因为尽管我之前已经关闭,但连接仍然打开。而且,这就是我不明白的。这怎么可能?
-
@JoséCarlos 你已经确实创建了一个全局单例(在
module.exports.clientPG中),只在该模块中创建了一个new Client,这是个坏主意。跨度>
标签: javascript node.js postgresql async-await