我正在尝试使用knex.js将10m 行插入MySQL数据库。是否有一种方法可以使用for循环插入长度为10000的阵列(似乎我可以插入的最大尺寸 - 任何大于此的内容都会获得"错误:er_net_packet_too_large:获得大于'max_allowed_packet'bytes的数据包"(。
我尝试使用一个前景链,但链条将很长以容纳10m的记录。
exports.seed = (knex) => {
// Deletes ALL existing entries
return knex('books').del()
.then(() => {
const fakeBooks = [];
for (let i = 0; i < 10000; i += 1) {
fakeBooks.push(createFakeBooks());
}
return knex('books').insert(fakeBooks)
.then(() => {
const fakeBooks1 = [];
for (let i = 0; i < 10000; i += 1) {
fakeBooks1.push(createFakeBooks());
}
return knex('books').insert(fakeBooks1)
.then(() => {
const fakeBooks2 = [];
for (let i = 0; i < 10000; i += 1) {
fakeBooks2.push(createFakeBooks());
}
...
如果您使用async
和await
并抛弃then
s,则更容易。然后可以像这样写:
exports.seed = async (knex) => {
await knex('books').del();
let fakeBooks = [];
for (let i = 1; i <= 10000000; i += 1) {
fakeBooks.push(createFakeBooks());
if (i % 1000 === 0) {
await knex('books').insert(fakeBooks);
fakeBooks = [];
}
}
};
await
将在函数继续之前进行承诺完成,而不会阻止线程。循环将运行一千万次,并每1000行插入数据库。您可以将其更改为10000行,但您不妨使用1000来确保。
我自己只尝试了一百万行,因为插入一千万的时间太多了。
您可以使用https://knexjs.org/#utility-batchinsert,用于将大量的行插入DB。
await knex.batchInsert('books', create10MFakeBooks(), 5000)
但是,您可能想在较小的批处理中实际创建这些书籍,以防止使用千兆字节的内存。因此,Mikas的答案是有效的,只需使用异步/等待,写作很琐碎。
我不会将KNEX用于此类工作,但是RAW SQL。