现在一直在努力导入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&amp;处于同一级别/客户端。
我已经尝试在Meteor.method()之外设置一个全局变量并将转换结果存储到其中,我也尝试使用Session.set(),但我似乎无法忍受在方法()之外得到转换结果。
感谢。
我的/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);
}
});
EUREKA MOMENT?
不应该是 / lib 而不是/ libs吗?也许reas没有及时定义?
如果我离开
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)
答案 0 :(得分:4)
我想找到一个解决方案,它不会将整个CSV文件加载到内存中,以便与大型数据集一起使用。这是我的解决方案,它使用Meteor.bindEnvironment和node-csv将CSV文件解析为Meteor Collection。
感谢#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');
});
}
答案 1 :(得分:2)
事实证明,因为CSV()使用回调并运行异步代码,我需要使用'Future'。有关更多说明,请参阅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
});