目录
介绍
在SQLAlchemy中,我们很熟悉filter和filter_by。但是,如果我们需要进行条件过滤怎么办。下面是创建自定义条件筛选器运算符的示例。
背景
这是另一种常见情况,当过滤器属性的值为null/empty或不满足特定需求时,我们需要忽略WHERE条件的一部分。如下图所示:
查询帮助程序
自定义查询类
为SQLAlchemy创建一个客户查询类以包含新filter_if方法。
这里condition是true,*criterion将应用为过滤器.
检查query_helper.py
from sqlalchemy.orm import Query
class CustomQuery(Query):
def filter_if(self: Query, condition: bool, *criterion):
if condition:
return self.filter(*criterion)
else:
return self
将查询类与db会话一起使用
将此自定义查询类添加到SQLAlchemy会话中,以使用新创建的filter_if方法。
database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
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通用类或基类
- GroupQueue数据库表,我们将在其中使用new运算符
models.py
class AppBaseModelOrm:
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
is_active = Column(Boolean, default=True) # soft delete
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)
class GroupQueue(AppBaseModelOrm, Base):
__tablename__ = "group_queues"
name = Column(String, index=True)
条件过滤
过滤器模型
这是一个FastApi pydantic模型
schemas.py
from sqlalchemy.orm import Query
class CustomQuery(Query):
def filter_if(self: Query, condition: bool, *criterion):
if condition:
return self.filter(*criterion)
else:
return self
使用filter_if
这里GroupQueueCrud是一个CRUD帮助程序类,检查正在调用或使用filter_if的search方法
group_queue_crud.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
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()
使用代码
Go to backend folder
Open cmd
Type docker-compose up -d
\backend> docker-compose up -d
project will run http://localhost:4003
Go to Api Doc
http://localhost:4003/docs#/
引用
使用自定义查询类python - SQLAlchemy - can you add custom methods to the query object? - Stack Overflow
https://www.codeproject.com/Articles/5307388/Conditional-filtering-in-SQLAlchemy-and-Python