我想读取一个csv文件,并使用grunt任务将每一行上载到沙发床。在这一点上,我还没有进行任何数据库验证,例如检查记录是否已经存在,但是在某些时候也必须这样做。

目前,这就是我正在执行的操作,问题仅在于名为people的第一个子任务的前65行被上载到beddb。

我知道这与异步执行有关,但无法解决该问题

Gruntils.js

csv2couch: {
    people: {
        db: 'http://localhost:5984/db',
        collectionName: 'person',
        src:['./data/schema3/people.csv']
    },
    organisms: {
        db: '<%= qmconfig.COUCHDBURL %>',
        collectionName: 'organism',
        src:['./data/schema3/organisms.csv']
    }

}


csv2couch.js

'use strict';

var nanolib = require('nano'),
    csv = require('csv'),
    urls = require('url'),
    fs = require('fs');

module.exports = function(grunt) {

    grunt.registerMultiTask('csv2couch', 'Parse csv file and upload data to couchdb.', function() {

        var done, parts, dbname, _this, collectionName;
        _this = this;
        done = this.async();
        parts = urls.parse(this.data.db);
        dbname = parts.pathname.replace(/^\//, '');
        collectionName = this.data.collectionName;

        // Merge task-specific and/or target-specific options with these defaults.
        var options = this.options({});

        // couchdb connection
        try {
            var nano = nanolib(parts.protocol + '//' + parts.host);
        } catch (e) {
            grunt.warn(e);
            done(e, null);
        }

        // database connection
        var db = nano.use(dbname);

        // process each source csv file
        this.filesSrc.forEach(function(f) {

            console.log('source file:', f);

            csv()
                .from.path(f, {
                    columns:true,
                    delimeter:',',
                    quote:'"'
                })
                .on('record', function(row,index){
                  console.log('#'+index, row);
                  save(row, collectionName);
                })
                .on('end', function(count){
                  console.log('Number of lines: '+count);
                  done();
                })
                .on('error', function(error){
                  console.log(error.message);
                  done(error);
                });
        });

        function save (data, collectionName) {

            // document ID is concatenation of collectionName and ID
            var docID = collectionName[0]+'_'+data.ID;

            // add some additional data
            data.type = collectionName;

            // insert data into couchdb
            db.insert(data, docID, function(err, body, header) {
              if (err) {
                console.log('[db.insert] ', err.message);
                return;
              }
            });
        }

    });

};

最佳答案

没错,异步代码不正确。保存所有记录之前,CSV文件将被读取到末尾。仅当最后一条记录已保存时,才需要调用完成。

您的保存方法需要进行回调

var rowsRead = 0,  // the number of rows read from the csv file
  rowsWritten = 0; // the number of rows written to CouchdDb


呼叫者:

.on('record', function(row,index){
  rowsRead++;
  save(row, collectionName, function(err){
    if(err){
      return done(err);
    }
    rowsWritten++;
    if(rowsRead===rowsWritten){ // check if we've written all records to CouchDb
      done();
    }
  });
})


保存方法:

function save (data, collectionName, callback) {
  // document ID is concatenation of collectionName and ID
  var docID = collectionName[0]+'_'+data.ID;

  // add some additional data
  data.type = collectionName;

  // insert data into couchdb
  db.insert(data, docID, callback);
}

07-28 09:44