Как вставить объемные данные в postgresql db из файла CSV? - PullRequest
0 голосов
/ 10 октября 2018

Мне нужно вставить более 100 записей, которые присутствуют в файле CSV, в базу данных PostgreSQL.Итак, я попробовал приведенный ниже код, он читает данные из файла, но не может вставить их в таблицу PostgreSQL, так есть ли другой способ сделать это?Как csvtojson и т. Д .?

const csv = require('csv');
var csvParser = require('csv-parse');

Controller.uploadCsv = async(data) => {
    fs.createReadStream(data.path)
        .pipe(csvParser({
            delimiter: '\t', 
            endLine: '\n', 
            escapeChar: '"', 
            enclosedChar: '"'
        }))
        .on('data', function(data) {
             console.log(data)// returning in console mentioned below
             console.log(data.name) // is undefined 

             const add = {
                name: data.name,
                address: data.address,
                phoneNo: data.phoneNumber,
                email: data.email,
                created_at: new Date(),
                updated_at: new Date()
            };
            const result = await models.table.create(add);
        })
        .on('end', function(data) {
             console.log('reading finished')
        })
}

router.js

router.post('/file', upload.single('file'),(req, res, next) => {
    Controller.uploadCsv(req.file)
        .then((result) => res.json(result))
        .catch(next)
})

данные консоли

    [ 'name',
      'address'
      'phoneNumber',
      'email',
      'created_at',
      'updated_at']
    [ 'aaa',
      'delhi',
      '1102558888',
      'test@gmail.com',
      '2017-10-08T06:17:09.922Z',
      '2018-10-08T06:17:09.922Z',]
    [ 'Oreo',
      'bgl',
      '1112589633',
      'test123@gmail.com',
      '2017-10-08T06:17:09.922Z',
      '2018-10-08T06:17:09.922Z' ]

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Вставьте ключевое слово async в функцию OnData.Помните, что это не последовательное выполнение, поэтому записи могут быть вставлены в совершенно ином порядке между выполнением одной программы и другой.

Заменить:

.on('data', function(data) {

На:

.on('data', async function(data) {
0 голосов
/ 06 ноября 2018

TL; DR. В вашем коде есть небольшая ошибка, которая может стать причиной вашей проблемы - когда вы используете await, для его запуска вам нужно поставить async до function на обработчике data - он может работать с небольшими файлами, но , пожалуйста, прочтите это не правильное решение - я добавил один из подходящих способов ниже .

ES6 async / await - это языковая конструкция, которая позволяет await разрешить Обещание и продолжить выполнение кода в функции async.В вашем коде у вас есть объявление async function, однако вы добавили await в не асинхронную функцию.Для пояснения - ключевое слово await будет разрешено только в том случае, если ближайший function() { равен async - в вашем случае это не так.

На самом деле я не думаю, что ваш код даже скомпилируется, и после некоторых изменений вы попадете прямо к проблеме, упомянутой в этом вопросе - это потому, что вы пытаетесь запуститьасинхронная операция на синхронном обработчике события в узле.Эта асинхронная вставка в базу данных будет запущена, но событие end сработает до завершения операций .

Чтобы сделать это правильно - вы можете использовать поток преобразования иливообще отказаться от потоковой передачи и просто использовать массив из CSV (для этого более чем достаточно хороших модулей).Однако я являюсь автором scramjet framework, и я также думаю, что это должно просто работать, как вы написали, или, может быть, даже проще.

Вот код, который будет делать то, что вы хотите:

const {StringStream} = require('scramjet');

Controller.uploadCsv = async(data) => 
    fs.createReadStream(data.path)
        .pipe(new StringStream('utf-8'))
        .CSVParse({
            delimiter: '\t', 
            newline: '\n', 
            escapeChar: '"', 
            quoteChar: '"'
        })
        .map(data => ({
            name: data.name,
            address: data.address,
            phoneNo: data.phoneNumber,
            email: data.email,
            created_at: new Date(),
            updated_at: new Date()
        }))
        .each(async entry => await models.table.create(entry))
        .each(result => log(result)) // if it's worth logging
        .run();

Scramjet просто использует потоки (все классы расширяют встроенные потоки node.js) внизу, но предоставляет интерфейс, похожий на синхронныйте, что в массиве и т. д. Вы можете запускать асинхронные операции, и он возвращает Promise из операции run.

...