在Python的SQL DBI中参数化带引号的字符串

时间:2015-01-26 22:32:42

标签: python postgresql python-db-api pg8000

我使用pg8000通过Python连接到PostgreSQL数据库。我希望能够通过cursor.execute方法发送日期作为参数:

def info_by_month(cursor, year, month):
    query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', '%s-%s-01')
    """
    cursor.execute(query, (year, month))
    return cursor

这会引发错误:InterfaceError: '%s' not supported in a quoted string within the query string。可以使用Python的字符串格式在那里插入日期。使用字符串格式化迷你语言提供了一种数据验证措施,以防止SQL注入攻击,但它仍然非常难看。

def info_by_month(cursor, year, month):
    query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', '{:04}-{:02}-01')
    """.format(year, month)
    cursor.execute(query)
    return cursor

如何将引用的字符串发送到cursor.execute方法?

2 个答案:

答案 0 :(得分:1)

提前执行format,然后将生成的字符串传递给execute。这样就可以避免 SQL注入的潜力,但仍然可以获得所需的格式。

e.g。查询变为:

query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', %s)"""

然后formatexecute变为:

dateStr = "{:04}-{:02}-01".format(year, month)
cursor.execute(query, dateStr)

我使用 psycopg2 ,但是 pg8000 符合相同的 DBI 标准,所以我希望这可以在中使用pg8000

答案 1 :(得分:0)

可以通过连接来做到这一点,从而损害可读性。

query = """
  SELECT *
  FROM info
  WHERE date_trunc('month', info.created_at) =
        date_trunc('month', %s || '-' || %s || '-01')
"""
cursor.execute(query, (year, month))