You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用SQLAlchemy过滤器?多方法多模型场景的实现需求

问题描述

我有一个类通过多种方法与SQLAlchemy对象交互,执行各类查询任务。部分查询使用相同的过滤器,示例如下:

def get_all_expired(self,my_model):
    q = session.query(my_model).filter(
        my_model.status == 'OK',
        my_model.is_validated == True,
        my_model.expires_at <= plum_dt.now(),
    )
    return q.all()

def update_all_expired(self,my_model):
    session.query(my_model).filter(
        my_model.status == 'OK',
        my_model.is_validated == True,
        my_model.expires_at <= plum_dt.now(),
    ).update({'status':'EXPIRED'})

上述两个方法的查询过滤器完全相同,且该过滤器还在其他方法中使用。我希望将其应用于不同模型,请问能否创建单一可复用的过滤器,统一管理并在需要的查询中复用?


解决方案

当然可以,以下两种简洁方式可实现可复用的SQLAlchemy过滤器,统一管理过滤逻辑:

方式一:独立过滤函数(最灵活)

创建单独函数接收模型类作为参数,返回组合好的过滤条件。这种方式无需修改模型定义,适用于任何包含对应字段的模型:

from sqlalchemy import and_
import plum_dt

def expired_filters(model):
    return and_(
        model.status == 'OK',
        model.is_validated == True,
        model.expires_at <= plum_dt.now()
    )

使用示例:

def get_all_expired(self, my_model):
    q = session.query(my_model).filter(expired_filters(my_model))
    return q.all()

def update_all_expired(self, my_model):
    session.query(my_model).filter(expired_filters(my_model)).update({'status':'EXPIRED'})

方式二:模型Mixin类(面向对象风格)

如果多个模型都包含status、is_validated、expires_at字段,可创建Mixin类封装字段定义和过滤逻辑,让模型继承后直接复用:

from sqlalchemy import Column, String, Boolean, DateTime, and_
import plum_dt

class ExpirableMixin:
    # 统一定义通用字段
    status = Column(String)
    is_validated = Column(Boolean)
    expires_at = Column(DateTime)

    @classmethod
    def get_expired_filters(cls):
        return and_(
            cls.status == 'OK',
            cls.is_validated == True,
            cls.expires_at <= plum_dt.now()
        )

模型继承示例:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class MyModel(Base, ExpirableMixin):
    __tablename__ = 'my_model'
    id = Column(Integer, primary_key=True)
    # 其他自定义字段...

使用示例:

def get_all_expired(self, my_model):
    q = session.query(my_model).filter(my_model.get_expired_filters())
    return q.all()

注意事项

  • 确保所有应用该过滤器的模型都包含对应字段,否则会抛出属性不存在的错误。
  • 若不同模型字段名有差异,可在过滤函数中添加参数适配(比如传入字段名映射),但建议尽量统一模型字段命名以简化维护。

内容的提问来源于stack exchange,提问作者KZiovas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:21:01