2014-11-13 3 views
0

Я понимаю, что подобные темы обсуждались, я просмотрел их все и попытался имитировать решения около 4 часов, но ни один из них, похоже, не решил проблему , Я бы не опубликовал это, исчерпав любое потенциальное решение, которое мог найти.JSON не будет вставляться в коллекцию Meteor (даже с Fiber или bindEnvironment)

Я пытаюсь преобразовать большой csv в JSON, а затем вставить его в свою коллекцию Meteor после преобразования.

Вот мой код, используя Meteor.bindElement подход:

if Meteor.isServer 
    @Fiber = Meteor.npmRequire("fibers") 
    Meteor.startup -> 
    #Converter Class 
     if Data.find().count() is 0 
      Converter = Meteor.npmRequire('csvtojson').core.Converter 
      fs = Meteor.npmRequire('fs') 
      csvFileName = '/Path/To/My/File.csv' 
      fileStream = fs.createReadStream(csvFileName) 
      #new converter instance 
      csvConverter = new Converter(constructResult: true) 
      #end_parsed will be emitted once parsing finished 
      csvConverter.on "end_parsed", (jsonObj) -> 
       console.log jsonObj 
       boundFunction = Meteor.bindEnvironment(-> 
        Data.insert jsonObj 
        return 
       , (e) -> 
         throw e 
         return 
       ) 

       insertToDB boundFunction 
       #read from file 
      fileStream.pipe csvConverter 
     return 

После анализа я могу войти в JSON просто отлично, но когда я пытаюсь добавить его в коллекцию, как это:

csvConverter.on "end_parsed", (jsonObj) -> 
    console.log jsonObj 
    Data.insert jsonObj 

Я получаю ошибку:

throw new Error("Meteor code must always run within a Fiber. " +   
W20141112-20:08:44.306(-8)? (STDERR)   ^
W20141112-20:08:44.306(-8)? (STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment. 
W20141112-20:08:44.306(-8)? (STDERR)  at Object.Meteor._nodeCodeMustBeInFiber (packages/meteor/dynamics_nodejs.js:9) 
W20141112-20:08:44.306(-8)? (STDERR)  at _.extend.get (packages/meteor/dynamics_nodejs.js:21) 
W20141112-20:08:44.306(-8)? (STDERR)  at Object.DDP.randomStream (packages/ddp/random_stream.js:69) 
W20141112-20:08:44.306(-8)? (STDERR)  at self._makeNewID (packages/mongo/collection.js:72) 
W20141112-20:08:44.306(-8)? (STDERR)  at Mongo.Collection.(anonymous function) [as insert] (packages/mongo/collection.js:485) 
W20141112-20:08:44.307(-8)? (STDERR)  at csvAdv.<anonymous> (server/startup.coffee:16:13) 
W20141112-20:08:44.307(-8)? (STDERR)  at csvAdv.emit (events.js:95:17) 
W20141112-20:08:44.307(-8)? (STDERR)  at csvAdv.<anonymous> (/Users/samuel_chordas/CurrentClasses/CSCI477a/JPL/JataTwo/packages/npm-container/.build.npm-container/npm/node_modules/csvtojson/libs/core/init_onend.js:9:10) 
W20141112-20:08:44.307(-8)? (STDERR)  at csvAdv.emit (events.js:117:20) 
W20141112-20:08:44.307(-8)? (STDERR)  at _stream_readable.js:929:16 
=> Exited with code: 8 

Какой я был в состоянии избавиться от обертыванием функции в волокне с помощью следующего кода, но он не запишет в свою коллекцию:

if Meteor.isServer 
    @Fiber = Meteor.npmRequire("fibers") 
    Meteor.startup -> 
    #Converter Class 
     if Data.find().count() is 0 
      Converter = Meteor.npmRequire('csvtojson').core.Converter 
      fs = Meteor.npmRequire('fs') 
      csvFileName = '/Path/To/My/File.csv' 
      fileStream = fs.createReadStream(csvFileName) 
      #new converter instance 
      csvConverter = new Converter(constructResult: true) 
      #end_parsed will be emitted once parsing finished 
      csvConverter.on "end_parsed", (jsonObj) -> 
       Fiber -> 
        Data.insert jsonObj 
       return 
      fileStream.pipe csvConverter 
     return 

Так что я пытался прибегать к использованию bindEnvironment, как показано в первом блоке кода, который приводит к тому же «Ошибка (« Код метеора должен всегда выполняться внутри Fiber »).

Вот моя коллекция в моей/Lib папки:

@Data = new Mongo.Collection 'data' 

Я довольно новый для Метеора Javascript и Coffescript поэтому любая обратная связь будет оценена.

Также я хотел бы добавить, что я не могу получить .run() для работы с Fiber.

+0

Самый простой способ сделать это - разобрать csv вне метеор и поместить полученный json-файл в ваш 'private', чтобы вы могли использовать [assets] (https://docs.meteor.com/#/ full/assets) api для чтения в файле. Я могу привести пример как ответ, если это звучит как приемлемая альтернатива. –

+0

@DavidWeldon Решение ниже работало, но мне все равно понравился бы пример, который мы должны использовать позже, если вы не возражаете. –

ответ

0

Попробуйте переформулировать определение boundFunction за пределами обработчика событий end_parsed.

boundFunction = Meteor.bindEnvironment((jsonObj) -> 
    Data.insert jsonObj 
    return 
, (e) -> 
    throw e 
) 

csvConverter.on "end_parsed", (jsonObj) -> 
    console.log jsonObj 
    boundFunction jsonObj 
    return 

Я подозреваю, что «код метеора должен всегда работать внутри волокна». ошибка не исходит от Data.insert, но от Meteor.bindEnvironment самой. Meteor.bindEnvironment

  • вызывается внутри «контекст Метеора»
  • принимает функцию
  • связывает эту функцию с тем же «контекстом Метеора», который bindEnvironment был назван из

В вашей реализации, к моменту звонка bindEnvironment, «Метеорный контекст» уже потерян, поэтому bindEnvironment не может ничего сделать, чтобы помочь.

+0

Это сработало! Спасибо!Проблема в том, что мы переполняем первичный ключ, но это совершенно отдельный. Еще раз спасибо. –