超时错误而插入JSON来Postgres数据库
我想我的文件插入到我的数据库,是包括对象数组(行)。我在25文件夹近八万个文件和近40000条记录。
我正在一个TimeoutError:ResourceRequest超时。
我尝试增加sequelize的连接时间,但它的第1000行之后给出了一个错误。我怎样才能插入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;
});
这部分代码是用文字异步和等待,这不是让他们连续读取,他们仍然能够并行运行。你要快,您可以拨打getData
功能,然后开始轰击models.dream.bulkCreate
。 bulkCreate
的使用是没有意义在这里无论是因为散装一个你不创造任何东西,而是一个
我可以看到这个选项有:
一)保持类似的代码,但25平行每块一个写去了文件25,这种变化有点大,在内存中读取25,把它们写散装数据库,阅读接下来的25,等等。 B)保持类似的代码,但25平行,每块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走,取决于如果我知道未来的时间最大尺寸/文件的数量。