node.js - 读取带标题的 csv,然后使用 node/grunt 将每一行上传到 couchdb

标签 node.js csv gruntjs couchdb couchdb-nano

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

目前,这就是我正在做的事情,问题只是第一个名为 people 的子任务的前 65 行正在上传到 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;
              }
            });
        }

    });

};

最佳答案

你是对的,异步代码不正确。在保存所有记录之前,将读取 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);
}

关于node.js - 读取带标题的 csv,然后使用 node/grunt 将每一行上传到 couchdb,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17015848/

相关文章:

mysql - 无法在 mysql 数据库中加载 '\' 字符

javascript - Node.js 中的端点与 Express 应用程序之间的冲突

node.js - 使用 Express 将元标记动态注入(inject) HTML

python - 使用 Pandas 计算每列出现的次数

javascript - 使用 grunt-exec 和 powershell 执行 linkchecker.exe

javascript - 正确发布一个 grunt 项目

javascript - Angular 手动引导在 IE 10 上不起作用

node.js - 将 Passport-local 与 Sailsjs 一起使用时没有响应

javascript - 如何减少数据图但保持极端

java - 使用Java读取文件时如何处理新行