是否有使用 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_ 结合起来,但我看不出这会如何使事情变得更容易——您仍然需要相同数量的ifs .【参考方案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 动态查询构建器?的主要内容,如果未能解决你的问题,请参考以下文章

烧瓶-sqlalchemy 或 sqlalchemy

Flask 学习-96.Flask-SQLAlchemy 判断查询结果是否存在的几种方式

是否可以扩展 Flask-restless 以添加新路线?

使用Flask SQLAlchemy从SQLite切换到MySQL

如果我的mysql套接字不在/ tmp中,是否可以将Mysql与SqlAlchemy和Flask一起使用?

如何在 Flask SQLAlchemy 中按多个条件进行过滤?