gpt4 book ai didi

node.js - 将 json 插入 Postgres 数据库时出现超时错误

转载 作者:行者123 更新时间:2023-12-03 22:38:26 28 4
gpt4 key购买 nike

我想将我的文件插入到我的数据库中,其中包括对象数组(行)。我在 25 个文件夹中有近 8000 个文件和近 40000 条记录。

我收到 TimeoutError: ResourceRequest 超时。

我尝试增加 sequelize 的连接时间,但在前一千行后出现错误。如何正确有效地将 40000 行数据插入到我的本地数据库中?

let folders_path = path.join(__dirname, "extracted_subjects/*");

function bulk_insert() {
glob(folders_path, readFolders);
}

function readFolders(err, folders) {
if (err) {
console.log("ERROR readFolders: ", err);
return;
}
folders.forEach(function(file) {
glob(path.join(file, "/*.json"), readFiles);
});
}
function readFiles(err, files) {
if (err) {
console.log("ERROR readFiles: ", err);
return;
}
files.forEach(async function(fileName) {
//console.log(fileName);
let promise = getData(fileName, "utf8")
.then(data => {
try {
// Parse And Bulk Create
let obj = JSON.parse(data);
models.dream
.bulkCreate(obj)
.then(function() {
console.log("File: inserted!");
})
.catch(err => console.log("Error", err));
} catch (SyntaxError) {
console.log("File: ", fileName);
return;
}
})
.catch(err => console.log(err));

await promise;
});
}

function getData(fileName, type) {
return new Promise(function(resolve, reject) {
fs.readFile(fileName, type, (err, data) => {
err ? reject(err) : resolve(data);
});
});
}

最佳答案

您可以增加连接的默认设置,例如(您可以在文档中阅读这些设置):

    dialectOptions:   {
timeout: 30
},
operatorsAliases: Sequelize.Op,
pool: {
max: 5,
min: 0,
idle: 30000,
maxConnections: 5,
maxIdleTime: 30
},

但我怀疑您最大的问题是您正在尝试读取所有文件并不断打开与数据库的新连接,而您没有时间将它们全部写入,它们自然会超时

我怀疑这种行为不是你想写的
files.forEach(async function (fileName) {
let promise = getData(fileName, 'utf8');
// ...
await promise;
});

这部分代码使用了 async 和 await 这两个词,这并不是让它们顺序读取,它们仍然能够并行运行。您将尽可能快地调用 getData 函数,然后开始轰炸 models.dream.bulkCreatebulkCreate 的使用在这里也没有意义,因为您没有批量创建任何东西,而是一个一个地创建

我可以看到的选项是:

a) 保留类似的代码,但并行处理 25 x 25 个文件,每个块写入一次,这个变化有点大,在内存中读取 25 个,在数据库中批量写入它们,读取下一个 25 个,等等......
b) 保留类似的代码,但并行处理 25 x 25 个文件,每个块写入 25 次,这个变化有点大,打开并读取 25 个文件,然后每个文件只写入一行,然后继续
c) 保留类似的代码,但不是读取每个文件并将其写入数据库,而是将它们保存在内存中,并在获得所有数据后在最后写入所有数据一次。但是,在您使用大数据的情况下,您可能会耗尽内存
d) 如果性能不是问题,因为你想要/需要做一次(一段时间),你可以简单地循环所有文件并以同步模式读取它们,所以它总是一个一个地进行。
files.forEach(async function (fileName) {
let data = fs.readFileSync(fileName, 'utf8'); // read the file sync

try {
let parsedData = JSON.parse(data); // try parsing
models.dream // and inserting
.create(parsedData) // this should not be bulkCreate, right??
// this is kinda wrong, it doesn't automatically mean it
// is inserted, but it is copy paste from above
.then(res => console.log('File: inserted!'))
.catch(err => console.log('Error', err));
} catch (SyntaxError) {console.log('File: ', fileName);}
};

这段代码的作用是确保您按顺序逐个文件地执行,它会大大减慢您的执行速度,但是由于您最初表示要在本地主机上执行此操作,因此我认为您有时间离开它运行。您仍然冒着读取文件的速度比数据库可以处理的写入速度快的风险,但是这次与同步读取下一个文件应该没有太大区别,并且您的系统应该能够跟上,特别是如果您增加允许的数量池中的连接。

对于生产方面,我可能会选择 a 或 b 选项,这取决于我是否提前知道文件的最大大小/数量。

关于node.js - 将 json 插入 Postgres 数据库时出现超时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54640554/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com