SQLAlchemy before_execute и связанные параметры - PullRequest
0 голосов
/ 24 апреля 2019

У меня есть функция, которую я добавил как обратный вызов before_execute для SQLAlchemy, например:

event.listen(self.app_engine, "before_execute", self.before_exec)

В этом обратном вызове я пытаюсь извлечь строковое представление оператора, который должен быть выполнен. Я узнал, что это не совсем тривиально - похоже, проблема заключается в запросах на основе ORM, а не в базовых, которые работают.

При компиляции запросов на основе ORM я сталкиваюсь с ошибками, подобными следующим:

sqlalchemy.exc.CompileError: Bind parameter 'widget_id' without a renderable value not allowed here.

Аргумент multiparams для before_execute заполняется для запроса ORM, но не для основного запроса. Поэтому я попытался сделать следующее:

clauseelement.values(**multiparams[0][0]).compile(compile_kwargs={"literal_binds": True})

Но, к сожалению, это просто приводит к:

sqlalchemy.exc.CompileError: Unconsumed column names: widget_id

Я не могу понять, как параметры сохраняются или обрабатываются, особенно когда вы добавляете слой в ORM. Я прочитал некоторые источники SQLAlchemy и все, что я могу найти в Интернете, но мне не очень повезло.

Вот большой контекст кода, который не работает:

def before_exec(self, conn, clauseelement, multiparams, params):
    if not isinstance(clauseelement, (dml.Delete, dml.Update)):
        return

    query = select([clauseelement.table])
    if clauseelement._whereclause is not None:
        query = query.where(clauseelement._whereclause)

    stmt_redo = clauseelement.compile(compile_kwargs={"literal_binds": True})

Основной стиль запроса, который работает:

self.session.query(Widget).filter_by(name="Foo").update({"name": "Baz"})

Запрос на основе ORM, который не работает:

        widget = self.session.query(Widget).filter_by(name="Foo").first()
        widget.name = "Baz"

        self.session.add(widget)
        self.session.commit()

Спасибо за ваше время!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...