【发布时间】: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 行。希望有更好的选择,这是常见的数据输入任务。
标签: mysql node.js csv asynchronous sequelize.js