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 を呼び出す必要があります。

save メソッドはコールバックを受け取る必要があります

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 に答える