是否有使用 Sqlalchemy 的 Flask 动态查询构建器?
Posted
技术标签:
【中文标题】是否有使用 Sqlalchemy 的 Flask 动态查询构建器?【英文标题】:Is there a dynamic query builder for Flask using Sqlalchemy? 【发布时间】:2017-10-11 03:11:51 【问题描述】:一个简单的查询如下所示
User.query.filter(User.name == 'admin')
在我的代码中,我需要检查正在传递的参数,然后根据参数从数据库中过滤结果。
例如,如果 User 表包含用户名、位置和电子邮件等列,则请求参数可以包含其中之一,也可以包含列的组合。我不想如下所示检查每个参数并链接过滤器,而是创建一个动态查询字符串,该字符串可以传递给一个过滤器并可以返回结果。我想创建一个单独的函数来评估所有参数并生成一个查询字符串。生成查询字符串后,我可以传递该查询字符串对象并获得所需的结果。我想避免使用 RAW SQL 查询,因为它违背了使用 ORM 的目的。
if location:
User.query.filter(User.name == 'admin', User.location == location)
elif email:
User.query.filter(User.email == email)
【问题讨论】:
【参考方案1】:您可以对查询重复应用filter
:
query = User.query
if location:
query = query.filter(User.location == location)
if email:
query = query.filter(User.email == email)
如果你只需要完全匹配,还有filter_by
:
criteria =
# If you already have a dict, there are easier ways to get a subset of its keys
if location: criteria['location'] = location
if email: criteria['email'] = email
query = User.query.filter_by(**criteria)
如果您出于某种原因不喜欢这些,我能提供的最好的方法是:
from sqlalchemy.sql.expression import and_
def get_query(table, lookups, form_data):
conditions = [
getattr(table, field_name) == form_data[field_name]
for field_name in lookups if form_data[field_name]
]
return table.query.filter(and_(*conditions))
get_query(User, ['location', 'email', ...], form_data)
【讨论】:
这就是我想要避免的,我需要在很多列上进行过滤,包括列的组合。想象一下我必须使用多少个 if。 @ShwetabhSharan:你能举个例子说明“列的组合”是个问题吗?请注意,至少列出所有可能的查找键是不可能避免的,除非您想将用户输入直接传递给 SQLAlchemy 函数(坏主意)。 举个例子,query = User.query if location: query = query.filter(User.location == location) if email: query = query.filter(User.email == email ) 如果位置和电子邮件:query = query.filter(User.email == email, User.location == location) 如果用户名和位置:query = query.filter(User.username == username, User.location == location ) 等 filter_by 似乎是目前最接近的。我在想是否有像我们在 Django 中一样可用的东西,叫做 Q docs.djangoproject.com/en/1.7/topics/db/queries/… @ShwetabhSharan:您不必进行组合。将过滤器应用于查询不会替换以前的过滤器。有一个等价于Q
,因为User.location == location
已经是一个条件,您可以将条件与and_
结合起来,但我看不出这会如何使事情变得更容易——您仍然需要相同数量的if
s .【参考方案2】:
写一个答案很晚,但如果有人正在寻找答案,那么sqlalchemy-json-querybuilder 会很有用。它可以安装为 -
pip install sqlalchemy-json-querybuilder
例如
filter_by = [
"field_name": "SomeModel.field1",
"field_value": "somevalue",
"operator": "contains"
]
order_by = ['-SomeModel.field2']
results = Search(session, "pkg.models", (SomeModel,), filter_by=filter_by,order_by=order_by, page=1, per_page=5).results
【讨论】:
【参考方案3】:https://github.com/kolypto/py-mongosql/
MongoSQL 是一个使用 JSON 作为输入的查询构建器。 能够:
选择要加载的列 加载关系 使用复杂条件进行过滤 订购 分页例子:
project: ['id', 'name'], // Only fetch these columns
sort: ['age+'], // Sort by age, ascending
filter:
// Filter condition
sex: 'female', // Girls
age: $gte: 18 , // Age >= 18
,
join: ['user_profile'], // Load the 'user_profile' relationship
limit: 100, // Display 100 per page
skip: 10, // Skip first 10 rows
【讨论】:
以上是关于是否有使用 Sqlalchemy 的 Flask 动态查询构建器?的主要内容,如果未能解决你的问题,请参考以下文章
Flask 学习-96.Flask-SQLAlchemy 判断查询结果是否存在的几种方式
使用Flask SQLAlchemy从SQLite切换到MySQL