[英]How do I use the SQLAlchemy ORM to do an insert with a subquery (moving data from one table to another)
以下簡單示例描述了我的 postgres DB 問題(盡管我的問題更多是關於 sqlalchemy 而不是 postgres):
我有一個名為detection
列的表:
我有另一個名為item
的表,其中包含以下列:
我想將某個商店的整個數據集從表detection
移動到表item
,同時還執行將美分轉換為美元的操作(該示例是理論上的,我的實際問題與美分到美元的操作不同)。
在原始 SQL 中,我可以使用以下查詢:
INSERT INTO item (detection_id, price_in_dollar)
SELECT id AS detection_id,
price_in_cent / 100 AS price_in_dollar
FROM detection
WHERE shop_id = {shop_id}
是否可以使用 SQLAlchemy 復制此查詢? 由於數據量很大(可能是數百萬行),我不想先下載數據進行操作,然后再上傳。 我的例子是:
q = session.query(Detection).filter(Detection.shop_id == shop_id)
for detection_record in q:
session.add(Item(detection_id=detection_record.id,
price_in_dollar=detection_record.price_in_cent / 100))
session.commit()
然而,這將首先將所有數據下載到機器上,而不是在數據庫本身中完成所有工作,因此具有與我的示例查詢不同的行為。
僅僅因為您在項目中使用 ORM 並不意味着您必須對所有內容都使用 ORM。 SQLAlchemy ORM 非常適合將關系“事物”拉下為 Python 對象並使用它們。 對於服務器端操作,SQLAlchemy Core 是使用的工具。
假設您已經使用聲明式聲明了 ORM 對象,例如,
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Detection(Base):
__tablename__ = "detection"
# ...
然后您可以使用 Core 使用如下代碼創建服務器端操作:
meta = Base.metadata
item_t = meta.tables[Item.__tablename__]
detection_t = meta.tables[Detection.__tablename__]
target_shop_id = 1 # test value
ins = item_t.insert().from_select(
["detection_id", "price_in_dollar"],
sa.select(
[
detection_t.c.id.label("detection_id"),
(detection_t.c.price_in_cents / sa.text("100")).label(
"price_in_dollar"
),
]
).where(detection_t.c.shop_id == target_shop_id),
)
with engine.begin() as conn:
conn.execute(ins)
生成的 SQL 文本為
INSERT INTO item (detection_id, price_in_dollar) SELECT detection.id AS detection_id, detection.price_in_cents / 100 AS price_in_dollar
FROM detection
WHERE detection.shop_id = ?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.