【问题标题】:Maximum recursion depth exceeded with SqlalchemySqlalchemy 超出了最大递归深度
【发布时间】:2017-01-13 01:08:31
【问题描述】:

我编写了这个循环来使用 Sqlalchemy 动态构建一个选择语句,以尝试减少 DB 命中。

我不明白为什么在调用 query.all() 时会出现最大递归深度超出错误。

当我将递归深度最大值更改为 2000 时,此查询工作正常。

代码:

filter_cond = False
for asset in assets:
    filter_cond = or_(filter_cond, and_(model.version == asset.get("version"),
                                        model.id == asset.get("id"),
                                        model.account_id == account_id))
query = session.query(model).filter(filter_cond)
result_set = query.all()

【问题讨论】:

    标签: python recursion sqlalchemy


    【解决方案1】:

    目前您正在 for 循环中递归地构建以下嵌套逻辑条件

    or(...or(or(false, condition1), condition2), ... conditionN)
    

    相反,如果你表达等价条件:

    or(condition1, condition2, ... conditionN)
    

    使用列表理解和解包,避免了递归。

    def condition(model, asset):
        return and_(model.version == asset.get("version"),
                    model.id == asset.get("id"),
                    model.account_id == account_id)
    
    filter_cond = or_(*[condition(model, asset) for asset in assets])
    

    【讨论】:

    • 完全避免列表组合和解包会更快吗,只做一个像这样的生成器:filter_cond = or_((AuthorizationTool.build_statement(model, asset, account_id) for asset in assets))
    • 不确定您的生成器表达式是否真的可以工作,并且回复:速度,如果性能是一个问题,请使用各种大小的 assets 测试块。
    • @RustyShackleford 生成器通过根据需要而不是预先生成元素来优化内存使用,而不是速度。代价是为每个元素额外调用生成器的next 方法。
    • @Haleemur Ali 它确实有效,我想 or_ 接受任何可迭代的
    猜你喜欢
    • 2015-09-25
    • 1970-01-01
    • 2013-12-01
    • 2018-03-31
    • 1970-01-01
    • 2017-03-24
    • 2011-12-31
    • 2017-08-09
    相关资源
    最近更新 更多