1

我在 nodejs 应用程序上使用 pgpromise。我正在做的一件事是更新许多记录,超过 10000 条记录。我这样做的原始方式是通过使用 db.tx,并返回一个批次。这种方法的唯一问题是一个需要一段时间,两个它将大量的 Promise 加载到一个数组中并消耗大量内存。

这是我目前所做的......

var worksheet = workbook.getWorksheet(1);
return db.tx(function (t) {
                    var insertStatements = [];
                    var upsertProcessedData = this.getSql('./sql/upsertProcessedData.sql');
                    for (var i = 2; i <= worksheet._rows.length; i++) {
                        // need to convert strings to dates for postgres insert
                        // console.log('Working row ' + i);
                        worksheet.getRow(i).getCell(8).value = new Date(worksheet.getRow(i).getCell(8).value);

                        // here we create a new array from the worksheet, as we need a 0 index based array.
                        // the worksheet values actually begins at element 1.  We will splice to dump the undefined element at index 0.
                        // This will allow the batch promises to work correctly... otherwise everything will be offset by 1
                        var arrValues = Array.from(worksheet.getRow(i).values);
                        arrValues.splice(0, 1);

                        // these queries are upsert.  Inserts will occur first, however if they error on the constraint, an update will occur instead.
                        insertStatements.push(this.one(upsertProcessedData, arrValues));
                    }
                    console.log('Begin inserts');
                    return t.batch(insertStatements);
                }).then( blah blah blah...)

这种方法有效,一旦我获得大量数据工作表,它就真的很慢。

我偶然发现了使用sequence,但很难理解它是如何工作的。根据文档,它声明像这样使用它..

function source(index, data, delay) {
    // must create and return a promise object dynamically, 
    // based on the index of the sequence; 
    switch (index) {
        case 0:
            return this.query('select 0');
        case 1:
            return this.query('select 1');
        case 2:
            return this.query('select 2');
    }
    // returning or resolving with undefined ends the sequence; 
    // throwing an error will result in a reject; 
}

db.tx(function (t) {
    // `t` and `this` here are the same; 
    return this.sequence(source);
})

我不明白的是如何允许我的“源”函数访问我的工作表中的数据?源函数中的“数据”参数来自哪里?似乎我不能只将我的工作表 obj 传递给我的源函数。
相反,我想尝试序列方法,但我不确定如何访问包含 sql 的查询文件,以及如何使用此序列函数迭代我的工作表......

编辑:所以在阅读了 Vitaly 写的关于序列的内容以及查看 github 问题之后,我想到了以下内容:

Promise.bind(promiseBindObject)
    .then(function (workbook) {
        return this.workbook.xlsx.readFile(this.fileName);
    }).then(function (workbook) {
        var worksheet = workbook.getWorksheet(1);
        // console.log(worksheet.name);
        var upsertProcessedRqData = db.getSql('./sql/upsertProcessedRqData.sql');
        function source(index, data, delay) {   
            // create and return a promise object dynamically,
            // based on the index passed;
            var arrValues = worksheet.getRow(index).values;
            if (index < worksheet._rows.length) {
                return this.this.one(upsertProcessedRqData, arrValues);
            }
            // returning or resolving with undefined ends the sequence;
            // throwing an error will result in a reject;
        }

        db.tx(function (t) {
            return t.sequence(source);
        ...

但是,问题是在我的“源”函数中,我的所有变量都超出了范围。但是,根据我所看到的,我不确定为什么会这样。在调试时,它只是说它们“不可用”。

4

0 回答 0