Вопрос:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) синтаксическая ошибка в или около ":"

python postgresql sqlalchemy

2913 просмотра

2 ответа

3925 Репутация автора

Вот мой запрос:

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 execute. Что я делаю неправильно?

Автор: dopatraman Источник Размещён: 08.11.2017 10:18

Ответы (2)


2 плюса

213208 Репутация автора

psycopg2не поддерживает :namedпараметры. Спецификация Python DB-API допускает :namedпараметры с paramstyle = 'named', но psycopg2использует:

>>> import psycopg2
>>> psycopg2.paramstyle
'pyformat'

как документально подтверждено в psycopg2документах .

Жаль, что DB-API Python допускает множество стилей параметров, но это так. Некоторые драйверы поддерживают изменение paramstyleкак расширение DB-API. Но не похоже, что 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})
>>> 

Поэтому, если вы видели, как :paramпараметры стиля работают раньше, это потому, что какой-то внешний слой (возможно, SQLAlchemy) адаптирует ваши запросы для вас. Беглый взгляд на документы по SQLAlchemy позволяет предположить, что это возможно .

По-видимому, вы обходите слой диалекта SQLAlchemy с вашим текущим кодом. Но я не знаю SQLAlchemy ...

Автор: Craig Ringer Размещён: 09.11.2017 03:46

6 плюса

29890 Репутация автора

Решение

Я никогда не сталкивался с проблемами перед передачей значений в SQLAlchemy execute. Что я делаю неправильно?

Возможно, вы использовали Session.execute()раньше, а не Engine.execute(). Первый автоматически оборачивает строки SQL с помощью text()конструкции, или, по крайней мере, он ведет себя так, как и здесь; это text()обеспечивает независимую обработку драйвером DB-API связанных параметров / заполнителей. Без этого вы будете в прихоти своего DB-API, как отметил Крейг Рингер в своем ответе .

Поэтому, чтобы :nameнапрямую использовать заполнители стилей с движком, просто оберните ваш запрос text():

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

Обратите внимание, что движок является отправной точкой приложения SQLAlchemy, и все строится на его основе, так что это может быть причиной того, что один не выполняет автоматическое перенос, в то время как другой делает. Сессия - это абстракция более высокого уровня.

Автор: Ilja Everilä Размещён: 09.11.2017 09:47
Вопросы из категории :
32x32