2017-02-10 32 views
3

也許我不完全瞭解承諾或Sequalize,但經過一段時間的處理後,感覺異步數據庫操作只適用於較簡單的情況。 並且通過詢問同步數據庫訪問的問題數量,它看起來並不是唯一的。Node.js數據庫從具有Sequelize的文件中插入

這是我的情況。假設我們有包含化合物的CSV文件,其中每行包含有關化合物的信息,以及以分號分隔的其成分列表。我們希望從其中填充成分表,但沒有重複。

例如,如果文件中包含的行

C1 INGA;在GB

C2 INGA;災害管理局

我們希望與三個記錄,INGA,在GB和全國災害管理局成分表。 所以當讀取行時,應該保存複合物,對於每個成分檢查是否已經存在,並且如果不添加它。以下是代碼:

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在表格中插入兩次。我的猜測是,找到或創建Sequelize方法返回承諾,並從數據庫插入文件行讀取速度更快。因此,當讀取新行並嘗試找到IngA時,第一行的IngA尚未插入。

我嘗試了幾種方法,但是對於這類任務來說,一切看起來都太複雜了。更重要的是,不起作用。

+1

如何分步實施?讀取數組中的所有值,刪除重複項並執行'bulkCreate'操作。 – piotrbienias

+0

正是我現在正在做的:)。但是它需要兩遍遍整個文件,並且處理沒有流 - 在內存中保存大Set對象,因爲CSV文件可以有400K行。希望有更好的選擇,這是常見的數據錄入任務。 –

回答

1

請以下罰款的解決方案,它應該工作。

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的幫助下,它將等待承諾完成它的執行,然後再執行下一個承諾。

相關問題