簡體   English   中英

如何使用 SQLAlchemy ORM 使用子查詢進行插入(將數據從一個表移動到另一個表)

[英]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列的表:

  • ID
  • 物品
  • price_in_cents
  • shop_id

我有另一個名為item的表,其中包含以下列:

  • ID
  • detection_id(detection.id 的外鍵)
  • price_in_dollar

我想將某個商店的整個數據集從表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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM