使用Express接收大块JSON数据并插入到PostgreSQL中

问题描述 投票:0回答:1

我想在问我的问题之前做一个简短的介绍。

下面的示例非常适合将400MB JSON文件作为流读取并将数据附加到PostgreSQL数据库中。

var fs = require('fs')
var JSONStream = require('JSONStream')
var es = require('event-stream')
var Pool = require('pg').Pool

var pool = new Pool({user: user, host: host, database: database, password: password, port: port})
var types = require('pg').types
types.setTypeParser(1114, str => str)

var getStream = function () {
    var jsond = 'export.json', //400MB File
        stream = fs.createReadStream(jsond, {encoding: 'utf8'}),
        parser = JSONStream.parse('*');
        return stream.pipe(parser);
};

var i = 0
getStream().pipe(es.mapSync(function (d){
    pool.query(`INSERT INTO metrics ("id","test") values ($1,$2)`,[d.id,d.test]).catch(console.error).then(function(){
        console.log('Inserted...', i++)
    })
}));

我使用下面的代码使用express和express-fileupload从上传表单中获取JSON文件。它也完美地工作(我省略了通常的标题):

server.js

app.post('/upload', function(req, res, next){
    if (!req.files || Object.keys(req.files).length === 0) {
        return res.status(400).send('No file');
    }

    let sampleFile = req.files.archive;

    sampleFile.mv(`${pathtoupload}}/upload.js`, function(err) {
        if (err) return res.status(500).send(err);
        res.send('File uploaded!');
    })
})

index.html

<div class="card">
    <div class="card-body">
        <div class="row">
            <div class="col-12 col-sm-12">
                <form method="POST" encType="multipart/form-data">
                    <input type="file" name="archive" />
                    <button type="submit" class="btn btn-success btn-lg"><i class="material-icons">cloud_upload</i> Send</button>
                </form>  
            </div>
        </div>
    </div>
</div>

<script>
        $("form").submit(function(e){
            e.preventDefault()

            var formData = new FormData(this)

            $.ajax({
                url: '/upload',
                type: 'POST',
                data: formData,
                //dataType: 'application/octet-stream',
                cache: false,
                contentType: false,
                processData: false,
                xhr: function() {
                    var myXhr = $.ajaxSettings.xhr();
                    if (myXhr.upload) {
                        myXhr.upload.addEventListener('progress', function(a) {
                            console.log('P',a)
                        }, false);
                    }
                    return myXhr;
                },
                success: function(data) {
                    alert('ok',data)
                },
            });
        });
</script>

问题:如何以表达,解析然后追加到数据库的方式接收大块JSON数据?

是否可以,或者我必须等待上传完成?

我尝试以下操作均未成功,仅在服务器控制台中没有'upload'的打印,但是在客户端上,我可以在控制台中看到正在上传的块]]

var JSONStream = require('JSONStream')
var es = require('event-stream')
var stream = require('stream');

app.post('/upload', function(req, res){
    console.log('upload')

    var readable = new stream.Readable({encoding: 'utf8'})

    req.on('data', function onRequestData(chunk){
        readable.push(chunk)
    })
    req.on('end', function(){
        res.send({})
    })

    var getStream = function () {
        parser = JSONStream.parse('*')
        return readable.pipe(parser)
    }

    getStream().pipe(es.mapSync(function(d){
        console.log(d)
        ///the pg insert part
    }))
})

在问我的问题之前,我想做一个简短的介绍。下面的示例非常适合将400MB JSON文件作为流读取并将数据附加到PostgreSQL数据库中。 var fs = ...

node.js express file-upload stream
1个回答
0
投票

我建议您为此使用pg-copy-streams。它使您可以将二进制数据直接流进表或从表流出。正是您所需要的。这是从NPM页面获取的示例:

© www.soinside.com 2019 - 2024. All rights reserved.