【问题标题】:Escaping dynamic sqlite query?转义动态sqlite查询?
【发布时间】:2012-09-12 13:42:33
【问题描述】:

我目前正在根据用户的输入构建 SQL 查询。可以在此处查看如何完成此操作的示例:

def generate_conditions(table_name,nameValues):
    sql = u""
    for field in nameValues:
        sql += u" AND {0}.{1}='{2}'".format(table_name,field,nameValues[field])
    return sql

search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"

if "Enhet" in args:
    search_query += generate_conditions("e",args["Enhet"])
c.execute(search_query)

由于每次我无法在执行调用中插入值时 SQL 都会更改,这意味着我应该手动转义字符串。但是,当我搜索每个人都指向执行...

我对生成查询的方式也不太满意,所以如果有人对另一种方式有任何想法,那也很棒!

【问题讨论】:

  • 表名和列名是事先知道的吗?

标签: python database sqlite escaping


【解决方案1】:

你有两个选择:

  1. 改用SQLAlchemy;它将使生成动态 SQL 更加pythonic 并且确保正确引用。

  2. 由于您不能对表名和列名使用参数,因此您仍然必须使用字符串格式将它们包含在查询中。另一方面,您的 应该始终使用 SQL 参数,前提是数据库可以准备语句。

    不建议直接从用户输入中插入表名和列名,以这种方式注入任意 SQL 语句太容易了。对照您接受的此类名称列表验证表名和列名。

    因此,以您的示例为基础,我会朝这个方向发展:

    tables = {
        'e': ('unit1', 'unit2', ...),   # tablename: tuple of column names
    }
    
    def generate_conditions(table_name, nameValues):
        if table_name not in tables:
            raise ValueError('No such table %r' % table_name)
        sql = u""
        params = []
        for field in nameValues:
            if field not in tables[table_name]:
                raise ValueError('No such column %r' % field)
            sql += u" AND {0}.{1}=?".format(table_name, field)
            params.append(nameValues[field])
        return sql, params
    
    search_query = u"SELECT * FROM Enheter e LEFT OUTER JOIN Handelser h ON e.Id == h.Enhet WHERE 1=1"
    
    search_params = []
    if "Enhet" in args:
        sql, params = generate_conditions("e",args["Enhet"])
        search_query += sql
        search_params.extend(params)
    c.execute(search_query, search_params)
    

【讨论】:

  • 感谢您的回复,我将仔细研究 SQLAlchemy,但是由于这实际上是我需要构建此类动态查询的唯一一次,如果 SQlAlchemy 看起来过大,我可能会选择第二个选项。
  • @monoceres:除了动态 SQL 生成之外,SQLAlchemy 还提供 ORM 和数据库抽象层。我在两个角色中都使用了这个库(通常同时)。一旦被采用,你往往不会回去。 :-)
猜你喜欢
  • 1970-01-01
  • 2021-01-13
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多