【问题标题】:Is there a dynamic query builder for Flask using Sqlalchemy?是否有使用 Sqlalchemy 的 Flask 动态查询构建器?
【发布时间】: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)

【问题讨论】:

    标签: python mysql flask-sqlalchemy


    【解决方案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
      }
      

      【讨论】:

        猜你喜欢
        • 2019-07-15
        • 2013-04-02
        • 2013-07-24
        • 2014-10-09
        • 2015-05-14
        • 1970-01-01
        • 2019-07-22
        • 1970-01-01
        • 2020-11-04
        相关资源
        最近更新 更多