SQLAlchemy ORM - 構建關係



本節描述建立另一個表,該表與我們資料庫中已存在的表相關。customers 表包含客戶的主資料。我們現在需要建立 invoices 表,該表可能包含屬於某個客戶的任意數量的發票。這是一種一對多關係的情況。

使用宣告式,我們定義此表及其對映類 Invoices,如下所示:

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship

class Customer(Base):
   __tablename__ = 'customers'

   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

class Invoice(Base):
   __tablename__ = 'invoices'
   
   id = Column(Integer, primary_key = True)
   custid = Column(Integer, ForeignKey('customers.id'))
   invno = Column(Integer)
   amount = Column(Integer)
   customer = relationship("Customer", back_populates = "invoices")

Customer.invoices = relationship("Invoice", order_by = Invoice.id, back_populates = "customer")
Base.metadata.create_all(engine)

這將向 SQLite 引擎傳送一個 CREATE TABLE 查詢,如下所示:

CREATE TABLE invoices (
   id INTEGER NOT NULL,
   custid INTEGER,
   invno INTEGER,
   amount INTEGER,
   PRIMARY KEY (id),
   FOREIGN KEY(custid) REFERENCES customers (id)
)

我們可以使用 SQLiteStudio 工具檢查 sales.db 中是否建立了新表。

Sales.db New Table

Invoices 類在 custid 屬性上應用 ForeignKey 構造。此指令指示此列中的值應約束為 customers 表中 id 列中存在的值。這是關係資料庫的核心特性,也是將不相關的表集合轉換為具有豐富重疊關係的“粘合劑”。

第二個指令,稱為 relationship(),告訴 ORM Invoice 類應使用屬性 Invoice.customer 與 Customer 類連結。relationship() 使用兩表之間的外部索引鍵關係來確定此連結的性質,確定它是一對多。

在 Customer 對映類下的 Customer.invoices 屬性上放置了額外的 relationship() 指令。relationship.back_populates 引數被分配為引用互補屬性名稱,以便每個 relationship() 可以對相同關係(以相反的方式表達)做出明智的決定。一方面,Invoices.customer 指的是 Invoices 例項,另一方面,Customer.invoices 指的是 Customers 例項的列表。

relationship 函式是 SQLAlchemy ORM 包的關係 API 的一部分。它提供兩個對映類之間的關係。這對應於父子或關聯表關係。

以下是找到的基本關係模式:

一對多

一對多關係是指使用子表上的外部索引鍵來引用父級。然後在父級上指定 relationship(),作為引用由子級表示的專案集合。relationship.back_populates 引數用於在多對一中建立雙向關係,其中“反向”側是多對一。

多對一

另一方面,多對一關係在父表中放置一個外部索引鍵以引用子級。relationship() 在父級上宣告,其中將建立一個新的標量持有屬性。這裡同樣使用 relationship.back_populates 引數來實現雙向行為。

一對一

一對一關係本質上是雙向關係。uselist 標誌指示在關係的“多”側放置標量屬性而不是集合。要將一對多轉換為一對一型別的關係,請將 uselist 引數設定為 false。

多對多

多對多關係是透過新增一個關聯表來建立的,該關聯表透過定義具有其外部索引鍵的屬性來關聯兩個類。它由 relationship() 的 secondary 引數指示。通常,Table 使用與宣告式基類關聯的 MetaData 物件,以便 ForeignKey 指令可以找到要連結的遠端表。每個 relationship() 的 relationship.back_populates 引數建立雙向關係。關係的兩側都包含一個集合。

廣告

© . All rights reserved.