mysql - 使用 KnexJS 查询 X 个表?

标签 mysql arrays node.js promise knex.js

我这里有一个独特的情况,我无法以优雅的方式解决。

用户传递了一组他们想要为其导出数据的信号。这个数组可以是 1 -> Any_Number,所以我首先根据传递的信号获取表名(每个信号将数据存储在一个单独的表中),并将它们存储在一个对象中。

下一步是遍历该对象(其中包含我需要查询的表名),对每个表执行查询并将结果存储在一个对象中,该对象将传递给 Promise 中的下一个链。我没有在网上看到任何处理此问题的好方法的示例,但我知道这是一个相当独特的场景。

在尝试添加对信号数组的支持之前,我的代码如下:

exports.getRawDataForExport = function(data) {
  return new Promise(function(resolve, reject) {

    var getTableName = function() {
      return knex('monitored_parameter')
        .where('device_id', data.device_id)
        .andWhere('internal_name', data.param)
        .first()
        .then(function(row) {
          if(row) {
            var resp = {"table" : 'monitored_parameter_data_' + row.id, "param" : row.display_name};
            return resp;
          }
        });
    }

    var getData = function(runningResult) {
      return knexHistory(runningResult.table)
        .select('data_value as value', 'unit', 'created')
        .then(function(rows) {
          runningResult.data = rows;
          return runningResult;
        });
    }

    var createFile = function(runningResult) {

      var fields = ['value', 'unit', 'created'],
          csvFileName = filePathExport + runningResult.param + '_export.csv',
          zipFileName = filePathExport + runningResult.param + '_export.gz';

      var csv = json2csv({data : runningResult.data, fields : fields, doubleQuotes : ''});

      fs.writeFileSync(csvFileName, csv);

      // create streams for gZipping
      var input = fs.createReadStream(csvFileName);
      var output = fs.createWriteStream(zipFileName);

      // gZip
      input.pipe(gzip).pipe(output);

      return zipFileName;

    }

    getTableName()
      .then(getData)
      .then(createFile)
      .then(function(zipFile) {
        resolve(zipFile);
      });
  });
}

显然这对单个表来说效果很好,我已经更新了 getTableName() 和 createFile() 方法来处理数据数组,所以这个问题只与 getData() 方法有关。

干杯!

最佳答案

这种问题远非独一无二,如果处理得当,很容易解决。

不要重写三个内部函数中的任何一个。

只需清除 explicit promise construction antipattern.getRawDataForExport() 返回一个自然发生的 promise 并将异步错误传播给调用者。

return getTableName()
.then(getData)
.then(createFile);

现在,.getRawDataForExport() 是您多次“获取”的基本构建 block 。

然后,设计选择;并行与顺序操作。两者都有很好的记录。

并行:

exports.getMultiple = function(arrayOfSignals) {
    return Promise.all(arrayOfSignals.map(getRawDataForExport));
};

顺序:

exports.getMultiple = function(arrayOfSignals) {
    return arrayOfSignals.reduce(function(promise, signal) {
        return promise.then(function() {
            return getRawDataForExport(signal);
        });
    }, Promise.resolve());
};

首先,为了获得最佳的潜在性能,请尝试并行。

如果服务器在并行操作时阻塞或可能永远阻塞,请选择顺序操作。

关于mysql - 使用 KnexJS 查询 X 个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43194875/

相关文章:

javascript - 拼接(0)与拼接(0,未定义)

javascript - 如何在不使用剪贴板的情况下从网站复制原始文本

PHP - 安全 MySQL 登录

MySQL - 行到列

mysql - 我们可以从数据库中删除 wp_woocommerce_sessions 吗?

java - 在Java中添加数组

php - Doctrine 2 保留实体并从插入查询中排除空字段

php - 如何根据深度值合并数组?

javascript - Puppeteer npm 如何从本地文件设置字体

node.js - node.js 和 redis 中的私有(private) channel 。如何?