#python #postgresql #sqlalchemy
#python #postgresql #sqlalchemy
Вопрос:
Я пишу запрос, который обновляет столбец таблицы, вычисляя разницу между его значением и столбцом из другой таблицы. В необработанном SQL это выглядит следующим образом:
UPDATE
products
SET
quantity = products.quantity - order_items.quantity
FROM
order_items
WHERE
order_items.order_id = %(order_id_1) s
AND products.code = order_items.product_code;
Я проверил документацию по SQLAlchemy и нашел раздел о update
выражении:
Предложение WHERE может ссылаться на несколько таблиц. Для баз данных, которые поддерживают это, будет сгенерировано предложение UPDATE FROM, или в MySQL, обновление с несколькими таблицами. Оператор завершится ошибкой в базах данных, которые не поддерживают операторы обновления с несколькими таблицами.
Я попытался реализовать запрос, как указано в документации:
query = (
products_table.update()
.values(quantity=products_table.c.quantity - order_items_table.c.quantity)
.where(
products_table.c.code
== select([order_items_table.c.product_code])
.where(
and_(
order_items_table.c.order_id == order_id,
order_items_table.c.product_code == products_table.c.code,
)
)
.as_scalar()
)
)
Но вместо краткого UPDATE ... SET ... FROM
выражения я получил это:
from sqlalchemy.dialects import postgresql
str(query.compile(dialect=postgresql.dialect()))
UPDATE
products
SET
quantity =(products.quantity - order_items.quantity)
WHERE
products.code = (
SELECT
order_items.product_code
FROM
order_items
WHERE
order_items.order_id = %(order_id_1) s
AND order_items.product_code = products.code
)
Более того, этот SQL-запрос не совсем корректен и не содержит требуемого FROM
оператора.
Поэтому я пытаюсь понять, что не так с моим выражением запроса и возможно ли вообще реализовать эквивалент необработанного SQL в SQLAlchemy без подзапроса. Есть идеи?
Версии
- ОС: macOS
- Python: 3.8.x
- SQLAlchemy: 1.3.20
- База данных: PostgreSQL 11.x
Заранее спасибо!
Ответ №1:
Кажется, я неправильно прочитал документацию. Ссылка, которую я опубликовал, объясняет обратное и предоставляет примеры написания запросов для баз данных, которые не поддерживают UPDATE FROM .
Я только что написал следующий запрос:
query = (
products_table.update()
.values(quantity=products_table.c.quantity - order_items_table.c.quantity)
.where(products_table.c.code == order_items_table.c.product_code)
.where(order_items_table.c.order_id == order_id)
)
и он генерирует правильный SQL:
UPDATE
products
SET
quantity =(products.quantity - order_items.quantity)
FROM
order_items
WHERE
products.code = order_items.product_code
AND order_items.order_id = %(order_id_1) s