我希望以前没有问过,我不确定要使用哪些关键字。
假设我想编写一个函数,该函数可以使用小于或等于查询的语句...
import MySQLdb
def query1(date,le):
'''
query1('2013-01',<= )
>>> 10
'''
query = '''
select *
from table
where number {x} 1
and date = {dt}
'''.format(dt=date,x=le)
cursor.execute(query)
rslt = cursor.fetchall()
return rslt
那么最好的方法是什么?
答案 0 :(得分:1)
您可以将比较运算符作为字符串传递给您的函数:
query1('2013-01', '<=')
这会将操作符的字符串插入到查询中,从而产生
select *
from table
where number <= 1
and date = 2013-01
请注意,通过插入字符串直接构建SQL查询是SQL注入的潜在向量。如果允许用户提供自己的日期字符串,则用户可以注入一些SQL代码并运行恶意代码。查看参数化以获取更多信息。
如果您想防止SQL注入,您应该执行以下操作。允许的运营商列表经过精心列入白名单,因此只能使用有效且安全的运营商。这用于构建查询。然后通过cursor.execute()
命令将日期注入查询。 MySQLdb
然后处理从您的数据构建安全查询,并且不允许恶意用户注入他们自己的SQL代替日期字符串。
import MySQLdb
def query1(date, comp):
query = '''
select *
from table
where number {comp} 1
and date = %s
'''.format(comp=sql_comp_operator(comp))
cursor.execute(query, (date, ))
return cursor.fetchall()
def sql_comp_operator(comp):
operators = {
'lt': '<',
'lte': '<',
'gt': '>',
'gte': '>=',
}
if comp in operators:
return operators[comp]
else:
raise ValueError("Unknown comparison operator '{}'".format(comp))
query1('2013-01', 'lte')
答案 1 :(得分:0)
理想情况下,您希望使用ORM来防止SQL注入攻击(我更喜欢SQLAlchemy / Elixir),这可以让您执行以下操作:
q = session.query(User).\
filter(User.id <= 1).\
filter(User.date_of_birth == date)
听起来你希望“le”成为你可以传入的函数/ lambda,但我不知道有什么方法可以将lambda转换为字符串以放入查询。例如,您可以将其称为:
query1('2013-01-01', lambda x,y: x <= y)
但我知道没有真正的方法可以将查询中的内容转换为“&lt; =”。但是,如果将其作为字符串传递,则可以使用带有命名块的格式,方法是使用与这些块具有相同名称的键传入字典,如下所示:
sql = """
select *
from table
where number {operation} 1
and date = '{date}'
"""
data = {
"operation": "<=",
"date": "2013-01-01"
}
query = sql.format(**data)