【问题标题】:Get and Add WHERE clause in SQL Query Python在 SQL 查询 Python 中获取和添加 WHERE 子句
【发布时间】:2021-12-01 11:19:31
【问题描述】:

我正在使用 Python 进行编码。我有这样的查询:

SELECT device_os, count(*) FROM warehouse WHERE device_year <= 2016 GROUP BY device_os;

现在,我有一些来自用户的动态过滤器。例如,

device_id IN (15, 85, 65) OR device_model in ('MAX', 'SHARP', 'AD')

我有这些额外的条件要应用于查询。所以,最终的查询应该变成:

SELECT device_os, count(*) FROM warehouse WHERE device_year <= 2016 AND (device_id IN (15, 85, 65) OR device_model in ('MAX', 'SHARP', 'AD')) GROUP BY device_os;

我搜索过sqlparse,但没有成功。我怎样才能让它看起来像我想要的那样?

【问题讨论】:

  • 你需要澄清这里的障碍,不清楚为什么你不能只使用最终查询?前任。输入清理、字符串格式化等
  • @talfreds 因为基本查询已经保存在某个地方,我需要在 where 子句中添加额外的过滤器,这些过滤器会动态出现。确保用户不会输入任何恶意输入。用户没有对数据库的直接控制权。
  • 我认为您可以选择解析用户文本(或使其成为field + list of values 而不是整个表达式,那么它应该很容易),或者使用有限的用户只有SELECT ON db.warehouse privs(限制够不够?)。

标签: python mysql sql sql-parser


【解决方案1】:

将 SQL 定义为模板格式字符串,然后将动态生成的条件代入其中。

sql_format = 'SELECT device_os, count(*) FROM warehouse WHERE device_year <= 2016 AND ({}) GROUP BY device_os;'
where_clause = 'device_id IN (%s, %s, %s) OR device_model in (%s, %s, %s)'
sql = sql_format.format(where_clause)
params = [15, 85, 65, 'MAX', 'SHARP', 'AD']
cursor.execute(sql, params)

如果没有附加条件,可以使用

where_clause = '1=1'

这是一个始终为真的条件,所以它不会改变结果。

【讨论】:

    【解决方案2】:

    我创建了一个名为 SQLGlot 的库,让这变得非常简单。

    import sqlglot
    import sqlglot.expressions as exp
    
    expression = sqlglot.parse_one("""
    SELECT device_os, count(*) FROM warehouse WHERE device_year <= 2016 GROUP BY device_os
    """) 
    
    def transform(node):
        if isinstance(node, exp.Where):
            node.args["this"] = sqlglot.parse_one(f"({node.this.sql()}) AND device_model in (1,2,3)")
        return node
    
    print(expression.transform(transform).sql(pretty=True))
    
    # output
    SELECT
      device_os,
      COUNT(*)
    FROM warehouse
    WHERE
      (device_year <= 2016)
      AND device_model IN (1, 2, 3)
    GROUP BY
      device_os
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-30
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-31
      相关资源
      最近更新 更多