SQLAlchemy错误:输入变量时“参数格式不能混合”

时间:2015-05-20 17:53:49

标签: python sql postgresql sqlalchemy psycopg2

我有一个Python脚本,它通过SQLAlchemy的connection.execute函数运行pgSQL文件。这是Python中的代码块:

results = pg_conn.execute(sql_cmd, beg_date = datetime.date(2015,4,1), end_date = datetime.date(2015,4,30))

这是变量在我的SQL中输入的区域之一:

WHERE
    (   dv.date >= %(beg_date)s AND
        dv.date <= %(end_date)s)

当我运行它时,我得到一个神秘的python错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) argument formats can't be mixed

...接着是一个有问题的SQL查询的大量转储。我以前使用相同的变量约定运行这个确切的代码。这次为什么不工作?

3 个答案:

答案 0 :(得分:6)

我遇到了与Nikhil类似的问题。我有LIKE子句的查询,直到我修改它以包含绑定变量,此时我收到以下错误:

DatabaseError: Execution failed on sql '...': argument formats can't be mixed

解决方案不是放弃LIKE子句。如果psycopg2根本不允许LIKE子句,那将是非常疯狂的。相反,我们可以使用%来逃避文字%%。例如,以下查询:

SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%';

需要修改为:

SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%%';

pscopg2文档中的更多详细信息:http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries

答案 1 :(得分:5)

事实证明,我在新的SQL查询中使用了一个SQL LIKE运算符,并且%操作数搞乱了Python的转义功能。例如:

    dv.device LIKE 'iPhone%' or
    dv.device LIKE '%Phone'

Another answer提供了一种解除逃逸和重新逃脱的方法,我认为这会为其他简单的代码增加不必要的复杂性。相反,我使用pgSQL处理正则表达式来修改SQL查询本身的能力。这将查询的上述部分更改为:

        dv.device ~ E'iPhone.*' or
        dv.device ~ E'.*Phone$'

对于其他人:您可能需要将LIKE运算符更改为正则表达式'〜'才能使其正常工作。请记住,大型查询的速度会慢一些。 (更多信息here。)

答案 2 :(得分:3)

对于我来说,事实证明我在SQL注释中有%

    /* Any future change in the testing size will not require 
       a change here... even if we do a 100% test
    */

这很好:

    /* Any future change in the testing size will not require 
       a change here... even if we do a 100pct test
    */