【问题标题】:Using node-csv and meteor-file to import CSV into a collection使用 node-csv 和 meteor-file 将 CSV 导入集合
【发布时间】:2013-10-19 07:13:48
【问题描述】:

苦苦挣扎了几个小时,现在尝试导入 CSV,使用 meteor-file 从客户端上传并使用 node-csv 服务器端转换为 CSV。我基本上需要使用用户上传的 CSV 文件中的数据填充我的集合。

/server/filehandler.js:

Meteor.methods({
'uploadFile': function (file) {

  if(file.start === 0) {
    console.log(file.name);
    console.log(file.type);
    console.log(file.size);            
  }

  file.save('/home/russell/tmp',{});
  var buffer = new Buffer(file.data);
  CSV().from(
          buffer.toString(),
          {comment: '#', delimiter: ',', quote: ''} 
      )
        .to.array( function(data){
          //console.log(data);

          for(var row=0; row<data.length; row++) {
              console.log(data[row]);
             newRecord = {
                  'firstname': data[row][0],
                  'lastname': data[row][1],
                  'email': data[row][2],
                  'emailshort': data[row][3],
                  'emailmain': data[row][4],
                  'domain': data[row][5]
              };
              console.log(newRecord);
              reas.insert(newRecord); // *** _dynamic_meteor ERROR here!
          }
        } );

 } // uploadFile
});

console.log 告诉我 CSV 到数组的转换没问题。

集合 reas 在 /lib/models.js 中设置为集合 - /lib 与 /server 和 /client 处于同一级别。

我尝试在 Meteor.method() 之外使用一个全局变量并将转换结果存储到该变量中,我也尝试使用 Session.set(),但我似乎无法在 method() 之外获取转换结果。

谢谢。

更新 - 2013 年 10 月 11 日

我的 /libs/models.js 看起来像这样:

reas = new Meteor.Collection("RegisteredEmailAddresses");

/*checks to see if the current user making the request to update is the admin user */
function adminUser(userId) {
    var adminUser = Meteor.users.findOne({username:"admin"});
                return (userId && adminUser && userId === adminUser._id);
            }

reas.allow({
    insert: function(userId, doc){
                        return adminUser(userId);
                    },
    update: function(userId, docs, fields, modifier){
                        return adminUser(userId);
                    },
    remove: function (userId, docs){
                        return adminUser(userId);
                    }
});

尤里卡时刻?!

不应该是 /lib 而不是 /libs 吗?也许没有及时定义reas?

2013 年 10 月 9 日更新

如果我离开队伍

reas.insert(newRecord);

我收到以下错误消息。如果我删除那条线,我不会。

错误信息:

W2036-20:56:29.463(1)? (STDERR) packages/mongo-livedata.js:1862
W2036-20:56:29.471(1)? (STDERR)         throw e;                                                              
W2036-20:56:29.475(1)? (STDERR)               ^
W2036-20:56:29.953(1)? (STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
W2036-20:56:29.958(1)? (STDERR)     at Object.Meteor.bindEnvironment (packages/meteor/dynamics_nodejs.js:60)
W2036-20:56:29.958(1)? (STDERR)     at null.<anonymous> (packages/meteor/helpers.js:108)
W2036-20:56:29.959(1)? (STDERR)     at MongoConnection.(anonymous function) [as insert] (packages/mongo-livedata/mongo_driver.js:491)
W2036-20:56:29.964(1)? (STDERR)     at Meteor.Collection.(anonymous function) [as insert] (packages/mongo-livedata/collection.js:448)
W2036-20:56:29.965(1)? (STDERR)     at app/server/server.js:37:20
W2036-20:56:29.966(1)? (STDERR)     at null.<anonymous> (/home/russell/.meteorite/packages/node-csv-npm/Dsyko/meteor-node-csv/01be0e3e834a4f033121cb3fcc92c2697741170d/.build/npm/node_modules/csv/lib/to.js:274:14)
W2036-20:56:29.967(1)? (STDERR)     at EventEmitter.emit (events.js:95:17)
W2036-20:56:29.971(1)? (STDERR)     at null.<anonymous> (/home/russell/.meteorite/packages/node-csv-npm/Dsyko/meteor-node-csv/01be0e3e834a4f033121cb3fcc92c2697741170d/.build/npm/node_modules/csv/lib/index.js:214:17)
W2036-20:56:29.972(1)? (STDERR)     at EventEmitter.emit (events.js:92:17)
W2036-20:56:29.975(1)? (STDERR)     at Transformer.end (/home/russell/.meteorite/packages/node-csv-npm/Dsyko/meteor-node-csv/01be0e3e834a4f033121cb3fcc92c2697741170d/.build/npm/node_modules/csv/lib/transformer.js:241:17)

【问题讨论】:

  • 也许我的问题与stackoverflow.com/questions/17788366/…有关?
  • 您的收藏是否使用var reas... 声明?如果是这样,请删除 var 以使其在整个应用程序中都可以访问。另外,错误信息的全文是什么?
  • 感谢马特,更新了以上内容以显示 models.js... 在此过程中我想我可能有解决方案(?)
  • 嗯。您的代码为我运行(即使在名为 libs 的目录中)。数据被插入到 Mongo 中。当您从命令行运行meteor mongo 并键入db.RegisteredEmailAddresses.find() 时会发生什么?我得到记录。您是否收到特定的错误消息? (检查流星控制台 - 而不是浏览器控制台。)
  • 感谢马特花时间回复。暂时无法测试。我会在周末做更多的黑客攻击并报告。

标签: csv collections import meteor


【解决方案1】:

事实证明,因为 CSV() 使用回调并运行异步代码,我需要使用“未来”。更多解释见http://gist.io/3443021

这是我的工作代码:

Meteor.methods({
     'uploadFile': function (file) {

      Future = Npm.require('fibers/future');

      console.log(file.name+'\'+file.type+'\'+file.size);                       

      file.save('/home/russell/tmp',{});
      var buffer = new Buffer(file.data);


      // Set up the Future
      var fut = new Future(); 

      // Convert buffer (a CSV file) to an array
      CSV().from(
                   buffer.toString(),
                   {comment: '#', delimiter: ',', quote: ''} 
                )
           .to.array( function(data){

                                       var newRecords=[];

                                       for(var row=0; row<data.length; row++) {
                                         console.log(data[row]);
                                         newRecord = {
                                                       'firstname': data[row][0],
                                                       'lastname': data[row][1],
                                                       'email': data[row][2],
                                                       'emailshort': data[row][3],
                                                       'emailmain': data[row][4],
                                                       'domain': data[row][5]
                                                     };

                                         //console.log(newRecord);
                                         newRecords.push(newRecord);
                                  }

                                  // at the end of the CSV callback
                                  // return newRecords via the Future
                                  fut['return'](newRecords);
    } );


    // Wait for the results of the conversion
    results = fut.wait();
    console.log('results================');
    console.log(results);

    // now insert the new records from the file into our collectiion
    if (results.length) {
        for(i in results) {
            reas.insert(results[i]);
        }
    }

    console.log('reas now looks like =====================');
    console.log(reas.find({}).fetch());

} // uploadFile

});

【讨论】:

    【解决方案2】:

    我想找到一个不将整个 CSV 文件加载到内存中的解决方案,以用于大型数据集。这是我使用 Meteor.bindEnvironment 和 node-csv 将 CSV 文件解析为 Meteor 集合的解决方案。

    感谢#meteor 上的人们的帮助。

    var csv = Meteor.require('CSV'); 
    var fs = Meteor.require('fs');
    var path = Npm.require('path');
    
    function loadData() {
      var basepath = path.resolve('.').split('.meteor')[0];
    
      csv().from.stream(
        fs.createReadStream(basepath+'server/data/enron_data.csv'),
          {'escape': '\\'})
        .on('record', Meteor.bindEnvironment(function(row, index) {
          Emails.insert({
            'sender_id': row[0]
            // etc.
            })
          }, function(error) {
              console.log('Error in bindEnvironment:', error);
          }
        ))
        .on('error', function(err) {
          console.log('Error reading CSV:', err);
        })
        .on('end', function(count) {
          console.log(count, 'records read');
        });
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多