使用 Sequelize 从文件插入 Node.js 数据库
Posted
技术标签:
【中文标题】使用 Sequelize 从文件插入 Node.js 数据库【英文标题】:Node.js database insertion from a file with Sequelize 【发布时间】:2017-06-28 20:35:57 【问题描述】:也许我不完全理解 Promise 或 Sequalize,但在使用它一段时间后,感觉异步 DB 操作仅适用于更简单的情况。 从要求同步数据库访问的问题数量来看,我不是唯一一个。
这是我的情况。假设我们有一个包含化合物的 CSV 文件,其中每一行包含有关化合物的信息,以及分号分隔的成分列表。我们想从中填充成分表,但没有重复。
例如,如果文件包含行
C1 IngA;IngB
C2 IngA;IngC
我们想要包含三个记录的成分表,IngA、IngB 和 IngC。 因此,当读取行时,它应该保存化合物,对于每个成分检查是否已经存在,如果不存在则添加它。代码如下:
var lineReader=require('readline').createInterface(
input: require('fs').createReadStream(filename)
);
lineReader.on('line', function(line)
let parts=line.split('\t');
compoundModel.create(
name: parts[0],
).then(entity =>
let ingredients=parts[1].split(';');
ingredients.forEach((ing, index) =>
ingModel.findOne(
where: name: ing
).then(ingEntity =>
if (ingEntity)
return ingEntity;
return ingModel.create(
name: ing
)
);
).then(ingEntity =>
//something else
);
);
);
问题是 IngA 被插入到表中两次。我的猜测是 find 或 create Sequelize 方法返回承诺,并且从文件中读取行比插入数据库更快。因此,当读取新行并尝试找到 IngA 时,尚未插入第一行的 IngA。
我尝试了几种方法,但对于这种任务来说,一切似乎都太复杂了。更重要的是,不起作用。
【问题讨论】:
分步做怎么样?读取数组中的所有值,去除重复项并执行bulkCreate
操作。
正是我目前正在做的事情:)。但它需要两次遍历整个文件,并且处理不是流式处理 - 在内存中保存大的 Set 对象,因为 CSV 文件可以有 400K 行。希望有更好的选择,这是常见的数据输入任务。
【参考方案1】:
您需要使用锁定进行交易。
执行表级锁定以防止在您的情况下发生幻读
http://docs.sequelizejs.com/en/v3/api/transaction/
【讨论】:
谢谢,我会尝试这种方法,目前按照 piotrbienias 的建议实施。【参考方案2】:请在下面的解决方案中很好,它应该可以工作。
var await = require('asyncawait/await');
var lineReader=require('readline').createInterface(
input: require('fs').createReadStream(filename)
);
lineReader.on('line', function(line)
let parts=line.split('\t');
compoundModel.create(
name: parts[0],
).then(entity =>
let ingredients=parts[1].split(';');
ingredients.forEach((ing, index) =>
await(ingModel.findOrCreate(
where: name: ing, defaults: name: ing,
).spread(function(_record, _created)
//Do something if required. _create will return true in case of entry already exists
))
).then(ingEntity =>
//something else
);
);
);
在执行此操作之前,请执行npm install asyncawait
。在await
的帮助下,它会等到promise 完成执行后再执行下一个promise。
【讨论】:
以上是关于使用 Sequelize 从文件插入 Node.js 数据库的主要内容,如果未能解决你的问题,请参考以下文章
由于带有 sequelize.js 的 UUID 外键,尝试将行插入表时出错
尝试将行插入表因为带有sequelize.js的UUID外键时出错
使用 Node.js/Sequelize 进行批量插入时 PostgreSQL 崩溃