【问题标题】:Formatting Errors when using cursor.execute()使用 cursor.execute() 时的格式错误
【发布时间】:2015-02-03 08:23:14
【问题描述】:

这是一段给我带来麻烦的代码

def process_message( msg):
    # deserialize msg
    id_dict = json.loads(msg)
    # extract id

    report_id = id_dict['id']
    print report_id
    sql = """ select  r.id,
            format('DATA "the_geom from (%s) as subquery
            using unique gid using srid=4326"', replace(replace(sql,'<<','%%'),'>>','%%')) as data,
            rcode,
            format('  VALIDATION
            ''userid'' ''^\d+$''
%s
  END',string_agg(format ('    ''%s'' ''%s''', paramname, prompt[1]),'
')) as validation
FROM report.reports r
JOIN report.reportparams rp on r.id = rp.reportid and not rp.del
where r.id = %s
group by r.id, sql, rcode;"""
    args = ('%s','%s','%s','%s','%s')
    cursor.execute(sql, args)
    row = cursor.fetchone()
    (id,data,rcode,validation) = row
    print (id,data,rcode,validation)
    exit

运行代码时出现的错误信息是这样的

Traceback (most recent call last):
  File "mapfile_queue_processor.py", line 60, in <module>
    process_message(  content  )
  File "mapfile_queue_processor.py", line 41, in process_message
    cursor.execute(sql, args)
psycopg2.ProgrammingError: type "s" does not exist
LINE 2:             format('DATA "the_geom from ('%s') as subquery
                                                   ^

现在,我根据人们之前的建议尝试了一些不同的修复方法,但都没有奏效。

在 sql 变量中,我尝试将所有 %s 设置为 %%s'%s''%%s'"%s""%%s" 甚至是 {s}其中

我似乎找到的唯一可能的解决方案是我不能有args = ('%s','%s','%s','%s','%s'),我需要有实际参数而不是'%s'

这是我的问题的解决方案吗? 如果是这样,我该怎么做?

如果不是解决方案,我该如何解决?

【问题讨论】:

    标签: python sql python-2.7 psycopg2


    【解决方案1】:

    cursor.execute() 中的 args 参数应该是您要传递给查询的真正参数(它们将代替 %s 占位符)。

    【讨论】:

      【解决方案2】:

      cursor.execute() 中,您的参数应该包含您要在查询中替换的真实参数(值),而不是“%s”。作为said in the documentation

      Psycopg 按类型将 Python 变量转换为 SQL 文字。许多标准 Python 类型已经适应了正确的 SQL 表示。

      示例:Python 函数调用:

      >>> cur.execute(
      ...     """INSERT INTO some_table (an_int, a_date, a_string)
      ...         VALUES (%s, %s, %s);""",
      ...     (10, datetime.date(2005, 11, 18), "O'Reilly"))
      

      转换成SQL命令:

      INSERT INTO some_table (an_int, a_date, a_string)
       VALUES (10, '2005-11-18', 'O''Reilly');
      

      使用 %(name)s 占位符也支持命名参数。使用命名参数,值可以以任何顺序传递给查询,并且许多占位符可以使用相同的值:

      >>> cur.execute(
      ...     """INSERT INTO some_table (an_int, a_date, another_date, a_string)
      ...         VALUES (%(int)s, %(date)s, %(date)s, %(str)s);""",
      ...     {'int': 10, 'str': "O'Reilly", 'date': datetime.date(2005, 11, 18)})
      

      【讨论】:

        【解决方案3】:

        我认为您不能使用参数绑定(即由 psycopg 处理的“%s”)在引用的内部查询中进行占位符替换。您必须自己构建一些查询字符串,转义您希望在查询中逐字结束的每个“%”。

        sql = "select 'Hello, %s' from bobs where id = %%s" % ("Bob",)
        cursor.execute( sql, [123] )
        

        显然你需要清理你的参数 - 我认为 psycopg 有一些可用的功能。

        【讨论】:

          猜你喜欢
          • 2020-06-13
          • 1970-01-01
          • 1970-01-01
          • 2020-12-06
          • 1970-01-01
          • 2020-10-08
          • 2014-07-26
          • 2021-12-03
          • 2020-08-06
          相关资源
          最近更新 更多