Executing JOINs
暗黙的な結合
関連するBasecamp オブジェクトのマップされたクラスが単一の外部キーリレーションシップを持つ場合、クラスは暗黙的に結合されます。必要なオブジェクトをインポートすると、以下の例のように、2つのマップされたクラス間にリレーションシップが確立されます。from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, String, Integer, DateTime, ForeignKey from sqlalchemy.orm import sessionmaker, relationship Base = declarative_base() class Contact(Base): __tablename__ = "Contact" Id = Column(Integer, primary_key=True) Name = Column(String) Email = Column(String) BirthDate = Column(DateTime) AccountId = Column(String, ForeignKey("Account.Id")) Account_Link = relationship("Account", back_populates="Contact_Link") class Account(Base): __tablename__ = "Account" Id = Column(String, primary_key=True) Name = Column(String) BillingCity = Column(String) NumberOfEmployees = Column(Integer) Contact_Link = relationship("Contact", order_by=Contact.Id, back_populates="Account_Link")
リレーションシップが確立されると、セッションのquery() メソッドを使用してテーブルが同時にクエリされます。
次に例を示します。
rs = session.query(Account, Contact).filter(Account.Id == Contact.AccountId) for Ac, Ct in rs: print("AccountId: ", Ac.Id) print("AccountName: ", Ac.Name) print("ContactId: ", Ct.Id) print("ContactName: ", Ct.Name)
他の結合形式
マップされたクラスに外部キーがないか、複数の外部キーがある場合、それらに対応するために異なる形式のJOIN クエリが必要になることがあります。 先ほどのクラスを例にすると、以下のJOIN クエリも可能です。- 明示的な条件(マップされたクラスに外部キーがない場合に必要):
rs = session.query(Account, Contact).join(Contact, Account.Id == Contact.AccountId) for Ac, Ct in rs:
- 左から右へのリレーションシップ:
rs = session.query(Account, Contact).join(Account.Contact_Link) for Ac, Ct in rs:
- 明示的なターゲットがある左から右へのリレーションシップ:
rs = session.query(Account, Contact).join(Contact, Account.Contact_Link) for Ac, Ct in rs:
- 文字列形式の左から右へのリレーションシップ:
rs = session.query(Account, Contact).join("Contact_Link") for Ac, Ct in rs: