1

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

目前这就是我正在做的事情,问题只是前 65 行,第一个名为的子任务people正在上传到 couchdb。

我知道这与异步执行有关,但无法弄清楚如何做到这一点

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;
              }
            });
        }

    });

};
4

1 回答 1

2

你是对的,异步代码不正确。在保存所有记录之前,正在将 CSV 文件读到底。只有在保存最后一条记录后,您才需要调用 done。

你的保存方法需要回调

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);
}
于 2013-06-10T15:39:01.037 回答