在python中传入le或ge标志

时间:2013-04-15 02:04:58

标签: python mysql

我希望以前没有问过,我不确定要使用哪些关键字。

假设我想编写一个函数,该函数可以使用小于或等于查询的语句...

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

那么最好的方法是什么?

2 个答案:

答案 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)