自定义SQLAlchemy查询过滤器

在数据库操作中,经常需要根据特定的条件来过滤查询结果。例如,在Web应用中,用户可能会通过表单提交一些过滤条件,希望根据这些条件来动态地构建查询。在PythonSQLAlchemy库中,可以通过定义自定义的查询类和方法来实现这一功能。本文将介绍如何创建一个自定义的条件过滤操作符。

在许多情况下,需要忽略一部分WHERE条件,当过滤属性的值为null/空或者不满足特定需求时。例如,可能需要在SQL查询中使用类似的功能,并且希望在SQLAlchemy和Python中实现相同的功能。

查询助手

自定义查询类

为了在SQLAlchemy中包含新的filter_if方法,需要创建一个自定义的查询类。

from sqlalchemy.orm import Query class CustomQuery(Query): def filter_if(self, condition: bool, *criterion): if condition: return self.filter(*criterion) else: return self

如果条件为真,则将criterion作为过滤条件应用。

使用查询类与数据库会话

将自定义查询类添加到SQLAlchemy会话中,以便使用新创建的filter_if方法。

from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base from db.query_helper import CustomQuery SQLALCHEMY_DATABASE_URL = "sqlite:///repo_app/data/test_sql_app.db" engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine, query_cls=CustomQuery) Base = declarative_base()

这样就可以在数据库会话中使用自定义的查询类了。

表模型

AppBaseModelOrm是一个通用的或基类,用于所有表模型。

class AppBaseModelOrm: id = Column(Integer, primary_key=True, index=True, autoincrement=True) is_active = Column(Boolean, default=True) created_by = Column(Integer) updated_by = Column(Integer, default=None) created_datetime = Column(DateTime(timezone=True), default=datetime.datetime.utcnow) updated_datetime = Column(DateTime(timezone=True), default=None, onupdate=datetime.datetime.utcnow) account_id = Column(Integer)

GroupQueue是一个数据库表,将在其中使用新的操作符。

条件过滤

Filter Model是一个FastApi pydantic模型。

class GroupQueueFilter(CamelModel): account_ids: List[int] = [] name: Optional[str] = None is_active: Optional[bool] = None from_created_datetime: Optional[datetime.datetime] = None to_created_datetime: Optional[datetime.datetime] = None

在这里,GroupQueueCrud是一个CRUD帮助类,检查search方法,它调用或使用filter_if方法。

class GroupQueueCrud(TableRepository): def __init__(self, db: Session): super().__init__(db=db, entity=models.GroupQueue) def search(self, filter: schemas.GroupQueueFilter): data = self.db.query(models.GroupQueue) \ .filter_if(filter.account_ids is not None and len(filter.account_ids), models.GroupQueue.account_id.in_(filter.account_ids)) \ .filter_if(filter.is_active is not None, models.GroupQueue.is_active == filter.is_active) \ .filter_if(filter.name is not None, models.GroupQueue.name.ilike(f"%{filter.name}%")) \ .filter_if(filter.from_created_datetime is not None, filter.from_created_datetime and models.GroupQueue.created_datetime >= filter.from_created_datetime) \ .filter_if(filter.to_created_datetime is not None, filter.to_created_datetime and models.GroupQueue.created_datetime <= filter.to_created_datetime) return data

使用这段代码,可以在数据库查询中根据条件动态地添加过滤条件。

使用代码

要运行项目,请转到后端文件夹,打开命令行,输入以下命令:

docker-compose up -d

项目将在http://localhost:4003上运行。

要查看API文档,请访问http://localhost:4003/docs。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485