摆脱动态的SQLite查询?(Escaping dynamic sqlite query?)

2019-07-31 13:24发布

我目前正在建设的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的每一次变化,我不能插在执行调用,这意味着我应该手动逃脱字符串值。 然而,当我搜索大家指出来执行...

我也并不满足于我如何生成查询,因此,如果有人有另一种方式将是巨大的也是任何想法!

Answer 1:

你有两个选择:

  1. 切换到使用的SQLAlchemy ; 它会让生成动态SQL很多更Python 确保适当的引用。

  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) 


文章来源: Escaping dynamic sqlite query?