Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中参数化带引号的字符串';s SQL数据库接口_Python_Postgresql_Python Db Api_Pg8000 - Fatal编程技术网

在Python中参数化带引号的字符串';s SQL数据库接口

在Python中参数化带引号的字符串';s SQL数据库接口,python,postgresql,python-db-api,pg8000,Python,Postgresql,Python Db Api,Pg8000,我正在使用pg8000通过Python连接到PostgreSQL数据库。我希望能够通过光标发送日期作为参数。执行方法: def info_by_month(cursor, year, month): query = """ SELECT * FROM info WHERE date_trunc('month', info.created_at) = date_trunc('month', '%s-%s-01') """ curs

我正在使用
pg8000
通过Python连接到PostgreSQL数据库。我希望能够通过
光标发送日期作为参数。执行
方法:

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”在查询字符串中的带引号的字符串中不受支持
。可以使用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

如何将带引号的字符串发送到
光标中。执行
方法?

提前执行
格式
,然后将结果字符串传递到
execute
。这样可以避免SQL注入的可能性,但仍然可以获得所需的格式

e、 g.查询变成:

query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', %s)"""
然后
格式
执行
变为:

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

我使用的是psycopg2,但pg8000似乎遵循相同的DBI标准,因此我希望这也适用于pg8000。

可以通过串联来实现,这会损害可读性

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

仅供参考,这就是我在第二段代码中提到的。我想知道是否有可能进一步改进。我的代码实际上与您的第二段代码不同。在第二个代码段中,您正在执行
格式
,然后将整个字符串传递给
execute
。这意味着您没有让SQL库执行任何插值。在我的示例中,我正在执行
格式
,然后将其作为参数传递给
执行
,SQL库可以根据需要执行插值,从而避免潜在的SQL注入。基本上,我的代码片段回答了您的问题“如何将带引号的字符串发送到cursor.execute方法?”标记为正确,因为它比我能想到的任何东西都更合理!谢谢很高兴提供帮助。我认为我的代码风格更具可读性,但我想这可能是我个人的偏好……同意。添加它只是为了记录的完整性。再次感谢您抽出时间回答。