使用node.js将数据从Oracle数据库流式传输到浏览器

时间:2019-03-07 06:24:53

标签: node.js oracle

我正在学习node.js和数据库。我正在尝试从oracle向客户端流传输约7,700,000行和96列的大量数据。后来我将这些数据用于虚拟表。但是在客户端中,它仅显示一行,然后在节点命令中,错误显示为“将标头发送到客户端后无法设置标头”。如何在客户端流数据。请帮助

var oracledb = require('oracledb');
const cors = require('cors');
var express = require('express');
var app = express();
app.use(cors());

oracledb.outFormat = oracledb.ARRAY;

oracledb.getConnection({
        user: 'user',
        password: 'password',
        connectString: 'some string'
    },
    (err, connection) => {
        if (err) {
            console.error(err.message);
            return;
        }
        var rowsProcessed = 0;
        var startTime = Date.now();
        var dataSize = 0;

        var stream = connection.queryStream(
            'SELECT * FROM table',
        );

        // stream.on('data', function (data) {
    //     rowsProcessed++;
    //     // console.log(JSON.stringify(data));
    //     // console.log(data);

    //     dataSize = dataSize + data.length;
    //     // oracleData.push(data);
    //     // console.log("pushing");
    //     // console.log(oracleData);
    //     // app.get('/data', (req, res) => {
    //     //     res.send(data);
    //     // })
    //     // console.log(data);
    // });

        app.get('/data', (req, res) => {
            stream.on('data', (data) => {
                rowsProcessed++;
                dataSize = dataSize + data.length;
                res.send(JSON.stringify(data));
            })
        })

        stream.on('end', function () {
            var t = ((Date.now() - startTime) / 1000);
            console.log('queryStream(): rows: ' + rowsProcessed +
                ', seconds: ' + t);
            // console.log(dataSize + ' bytes');
            connection.close(
                function (err) {
                    if (err) {
                        console.error(err.message);
                    } else {
                        console.log("connection closed")
                    }
                }
            )
        })

    }
);


app.listen(5000, () => {
    console.log('Listening at 5000')
})

我尝试使用上述方法。但这是失败的。如何获得输出? 如果我一次输出全部数据,浏览器就会死机,这就是为什么我尝试使用流式传输,并且如果我一次加载全部数据,则在node命令提示符下它会显示内存不足。

谢谢。

1 个答案:

答案 0 :(得分:0)

您要做的第一件事是更好地组织应用程序。关注点分离很重要,您应该有一个连接池等。请看一下本系列的一些想法:https://jsao.io/2018/03/creating-a-rest-api-with-node-js-and-oracle-database/

一旦您弄清楚了组织,就结合这个示例来展示大量结果。

const oracledb = require('oracledb');

async function get(req, res, next) {
  try {
    const conn = await oracledb.getConnection();

    const stream = await conn.queryStream('select * from employees', [], {outFormat: oracledb.OBJECT});

    res.writeHead(200, {'Content-Type': 'application/json'});

    res.write('[');

    stream.on('data', (row) => {
      res.write(JSON.stringify(row));
      res.write(',');
    });

    stream.on('end', () => {
      res.end(']');
    });

    stream.on('close', async () => {
      try {
        await conn.close();
      } catch (err) {
        console.log(err);
      }
    });

    stream.on('error', async (err) => {
      next(err);

      try {
        await conn.close();
      } catch (err) {
        console.log(err);
      }
    });
  } catch (err) {
    next(err);
  }
}

module.exports.get = get;

如果您发现自己做的很多,请通过创建可重复使用的转换流来简化操作:

const oracledb = require('oracledb');
const { Transform } = require('stream');

class ToJSONArray extends Transform {
  constructor() {
    super({objectMode: true});

    this.push('[');
  }

  _transform (row, encoding, callback) {
    if (this._prevRow) {
      this.push(JSON.stringify(this._prevRow));
      this.push(',');
    }

    this._prevRow = row;

    callback(null);
  }

  _flush (done) {
    if (this._prevRow) {
      this.push(JSON.stringify(this._prevRow));
    }

    this.push(']');

    delete this._prevRow;

    done();
  }
}

async function get(req, res, next) {
  try {
    const toJSONArray = new ToJSONArray();
    const conn = await oracledb.getConnection();

    const stream = await conn.queryStream('select * from employees', [], {outFormat: oracledb.OBJECT});

    res.writeHead(200, {'Content-Type': 'application/json'});

    stream.pipe(toJSONArray).pipe(res);

    stream.on('close', async () => {
      try {
        await conn.close();
      } catch (err) {
        console.log(err);
      }
    });

    stream.on('error', async (err) => {
      next(err);

      try {
        await conn.close();
      } catch (err) {
        console.log(err);
      }
    });
  } catch (err) {
    next(err);
  }
}

module.exports.get = get;
相关问题