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

Nik*_*hil 5 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))
Run Code Online (Sandbox Code Playgroud)

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

WHERE
    (   dv.date >= %(beg_date)s AND
        dv.date <= %(end_date)s)
Run Code Online (Sandbox Code Playgroud)

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

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) argument formats can't be mixed
Run Code Online (Sandbox Code Playgroud)

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

Dav*_*arx 9

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

DatabaseError: Execution failed on sql '...': argument formats can't be mixed
Run Code Online (Sandbox Code Playgroud)

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

SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%';
Run Code Online (Sandbox Code Playgroud)

需要修改为:

SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%%';
Run Code Online (Sandbox Code Playgroud)

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


Nik*_*hil 8

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

    dv.device LIKE 'iPhone%' or
    dv.device LIKE '%Phone'
Run Code Online (Sandbox Code Playgroud)

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

        dv.device ~ E'iPhone.*' or
        dv.device ~ E'.*Phone$'
Run Code Online (Sandbox Code Playgroud)

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


小智 5

对我来说,结果是我%在 sql 评论中

    /* Any future change in the testing size will not require 
       a change here... even if we do a 100% test
    */
Run Code Online (Sandbox Code Playgroud)

这工作正常:

    /* Any future change in the testing size will not require 
       a change here... even if we do a 100pct test
    */
Run Code Online (Sandbox Code Playgroud)