2017-03-08 6 views
0

Ich importiere Daten aus einer CSV-Datei in ein Nodejs-System mit Sequelize, aber ich habe Probleme, zu überprüfen, ob eine vorherige Zeile zuvor eingefügt wurde.Sequelize commit nach jedem Einfügen

Dies ist der Code, den ich

exports.insertEmployee = function (employee) { 
    return new Promise((fulfill, reject) => { 
     models.Employee.create(employee) 
     .then(employee => fulfill(employee.dataValues)) 
     .catch(reject); 
    }); 
}; 

exports.importEmployee = function (employee) { 
    return new Promise((fulfill, reject) => { 
     models.Employee.findOne({where: {customID: employee.customID}, raw: true}).then(emp => { 
      if(emp) { 
       fulfill(emp); 
      } 
      else { 
       exports.insertEmployee(employee).then(fulfill); 
      } 
     }); 
    }); 
}; 

Die Funktion importEmployee verwendet, wird so oft wie Linien gibt es in der csv wie diese

lines.forEach(line => { 
    let emp = line.employee; 
    importEmployee(emp).then(employee => {console.dir(employee)}); 
}); 

Das Problem, das ich habe angerufen werden Wenn ich überprüfe, ob ein Benutzer mit der gleichen customID bereits eingefügt wurde, hat die Datenbank den Einsatz noch nicht festgeschrieben, so dass immer false zurückgegeben wird und ich doppelte Mitarbeiter mit der gleichen benutzerdefinierten ID

habe

Wie könnte ich das beheben? Ich habe versucht, Transaktionen zu verwenden, aber vielleicht mache ich es falsch, weil es nicht hilft.

Danke!

Antwort

1

Es hat nicht funktioniert, weil Sie innerhalb Ihrer forEach Reihe von asynchronen Operationen durchführen wollten. Auf diese Weise werden alle Datensätze eingefügt, da die Operationen, die das Prüfen und Einfügen durchführen, gleichzeitig ausgeführt werden. Um diese Situation zu vermeiden, können Sie die Promise-Funktion mapSeries() von Bluebird Modul verwenden. Es ist in die Fortsetzung integriert, so dass kein zusätzliches Paket installiert werden muss.

Darüber hinaus können Sie die Überprüfung und Einfügen über eine einzige Operation namens findOrCreate(), die eine Instanz und boolean gibt, wenn diese Instanz erstellt wurde oder einfach als eine vorhandene zurückgegeben.

Wenn beide diese Funktionen zu kombinieren, ermöglicht Betrieb wird sehr einfach und unkompliziert

// here is the function performing findOrCreate 
exports.createEmployee = function(employee) { 
    return models.Employee.findOrCreate({ 
     where: { customID: employee.customID }, 
     defaults: employee 
    }); 
}; 

Was mehr ist, Sie müssen nicht verschachtelten Promises erstellen, so wie du in insertEmployee und importEmployee tat. Die meisten Sequelize-Funktionen geben bereits Versprechungen zurück, sodass Sie einfach den Funktionsaufruf selbst zurückgeben können.

Jetzt können Sie über lines iterieren und rufen Sie die createEmployee Methode.

models.sequelize.Promise.mapSeries(lines, (employee) => { 
    return createEmployee(employee); 
}).then(result => { 
    console.log(result); 
    // example output: [ [ Instance, true ], [ Instance, true ], [ Instance, false ] ] 
}); 

Die Boolesche true bedeutet, dass die Instanz erzeugt wurde, während false bedeutet, dass beispielsweise aus der Tabelle zurückgeführt wurde, weil solche Aufzeichnung bereits vorhanden ist.

Verwandte Themen