首页 > 解决方案 > KnexJS RangeError:超出最大调用堆栈大小

问题描述

我在 nodejs 中有以下 knex 查询。此查询的目标是删除rule三个表中任何一个不是外键的表中的所有行:rule_setrule_in_progressrule_pending。也就是说,删除rule基本上未使用的所有行。

deleteUnusedRules(txn) {
    const conn = txn ? txn : knex;
    return conn.table('rule').delete()
        .whereNotIn('rule.id', function() {
            this.table('rule_in_progress').select('rule_in_progress.rule_id')
                .union(this.table('rule_pending').select('rule_pending.rule_id')
                    .union(this.table('rule_pending').select('rule_pending.rule_id')
                        .union(this.table('rule_set').select('rule_set.rule_id'))
                    )
                );
        });
}

但它会引发以下错误

stack=RangeError: Maximum call stack size exceeded

我在网上找不到任何解决方案。

标签: node.jsknex.js

解决方案


我想,因为您使用 subquerybuilderthis进行所有联合查询,所以 knex 内部的某些东西会循环引用该查询......

基本上每次调用时,this.table您都不是在创建新的子查询,而是在修改同一个构建器。

也许你试图这样做:

deleteUnusedRules(txn) {
    const conn = txn ? txn : knex;
    return conn.table('rule').delete()
        .whereNotIn('rule.id', conn.table('rule_in_progress').select('rule_in_progress.rule_id')
                .union(conn.table('rule_pending').select('rule_pending.rule_id')
                    .union(conn.table('rule_pending').select('rule_pending.rule_id')
                        .union(conn.table('rule_set').select('rule_set.rule_id'))
                    )
                )
        );
}

最重要的是,联合选择查询被创建为单独的查询构建器实例,它们不共享状态。


推荐阅读