sqlalchemy.exc.ProgrammingError:(psycopg2.ProgrammingError)语法错误在或附近":"

时间:2017-11-08 22:18:38

标签: python postgresql sqlalchemy

这是我的疑问:

QUERY = """
        UPDATE my_table
        SET
            my_prop=:foo
        WHERE hello='world'
"""

我执行这样的声明:

sqlalchemy_engine.execute(QUERY, foo='bar')

当我这样做时,我收到以下错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) syntax error at or near ":"
UPDATE my_table\n        SET\n            my_prop.foo = :foo
                                                         ^

在将值传递给SQL Alchemy执行之前,我从未遇到过问题。我做错了什么?

2 个答案:

答案 0 :(得分:6)

  

在将值传递给SQLAlchemy执行之前,我从未遇到过问题。我做错了什么?

您之前可能一直在使用Session.execute(),而不是Engine.execute()。前者使用text()构造自动包装SQL字符串,或者至少它的行为如此,这是关键所在;它是text(),它为DB-API驱动程序提供绑定参数/占位符的独立处理。没有它,您可以随心所欲地使用DB-API as noted by Craig Ringer in their answer

因此,为了直接使用:name样式占位符和引擎,只需使用text()包装您的查询:

sqlalchemy_engine.execute(text(QUERY), foo='bar')

请注意,SQLAlchemy应用程序的引擎is the starting point和所有内容都构建在它之上,因此这可能是不进行自动换行的原因,而另一个则是。会话是更高级别的抽象。

答案 1 :(得分:2)

psycopg2不支持:named个参数。 The Python DB-API spec允许使用:named的{​​{1}}参数,但paramstyle = 'named'使用:

psycopg2

as documented in the psycopg2 docs

遗憾的是,Python的DB-API允许各种参数样式,但事实就是如此。某些驱动程序似乎支持将>>> import psycopg2 >>> psycopg2.paramstyle 'pyformat' 更改为DB-API扩展。但它看起来不像paramstyle就是其中之一:

psycopg2

因此,如果您之前看到>>> psycopg2.paramstyle = 'named' >>> psycopg2.paramstyle 'named' >>> cur.execute("SELECT :a, :b, :c", {'a': 1, 'b': 2, 'c': 3}) Traceback (most recent call last): File "<stdin>", line 1, in <module> psycopg2.ProgrammingError: syntax error at or near ":" LINE 1: SELECT :a, :b, :c >>> conn.rollback() >>> cur.execute("SELECT %(a)s, %(b)s, %(c)s", {'a': 1, 'b': 2, 'c': 3}) >>> 样式参数有效,那么因为某些外层(可能是SQLAlchemy)正在为您调整查询。快速查看SQLAlchemy docs表明it may do just that

猜测,您正在使用当前代码绕过SQLAlchemy方言图层。但我真的不懂SQLAlchemy ......