建立一個關系
from sqlalchemy import Column, Integer, String, MetaData, ForeignKey from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, backref metadata = MetaData() Base = declarative_base(metadata=metadata) class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) password = Column(String) def __repr__(self): return "<User(name='%s', password='%s')>" % (self.name, self.password)
第二個表Address與User
關聯,可以被映射和查詢。Users 在可以存儲任意數量的電子郵件地址關聯的用戶名。這意味着一個從users
到一個存儲電子郵件地址的新表Addresses
的一對多
關聯。我們在Address
中使用聲明定義這張表與User
的映射:
class Address(Base): __tablename__ = 'addresses' id = Column(Integer, primary_key=True) email_address = Column(String, nullable=False) #ForeignKey函數是一個應用於Column的指令,表明這一列的值應該保存指定名稱的遠程列的值。 user_id = Column(Integer, ForeignKey('users.id')) user = relationship("User", backref='addresses', lazy='dynamic') def __repr__(self): return "<Address(email_address='%s')>" % (self.email_address) # 第一個參數為對應參照的類User,第二個參數backref表示給關聯的數據庫模型添加一個屬性 # 第三個參數lazy決定了什么時候SQLALchemy從數據庫中加載數據。 # relationship()的參數中有一個稱為backref()的relationship()的子函數,反向提供詳細的信息, # 即在users中添加User對應的Address對象的集合,保存在User.addresses中。
上述類使用了ForeignKey
函數,它是一個應用於Column
的指令,表明這一列的值應該保存指定名稱的遠程列的值
。這是關系數據庫的一個核心特征,是“膠水”,將原本無關的表變為有豐富的重疊關系的集合。上面的ForeignKey
表示,Addresses.user_id
列的值應該等於users.id
列中的值,即,users
的主鍵。
第二個函數,稱為relationship()
, 它告訴 ORM ,Address
類本身應該使用屬性Address.user
鏈接到User
類。relationship()
使用兩個表之間的外鍵關系來確定這個鏈接的性質,這個例子中,確定Address.user
將要成為多對一
中多的一側。relationship()
的參數中有一個稱為backref()
的relationship()
的子函數,反向提供詳細的信息, 即在users
中添加User
對應的Address
對象的集合,保存在User.addresses
中。多對一
關系的反向始終是一對多
的關系。一個完整的可用的relationship()
配置目錄在基本關系模式。
兩個互補關系, Address.user
和User.addresses
被稱為一個雙向關系,並且這是SQLAlchemy ORM
的一個關鍵特性。
#models.py class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) users = db.relationship('User', backref='role', lazy='dynamic') class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) password_hash = db.Column(db.String(128)) role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), nullable=True) ticketholiday_id = db.relationship('Ticketholiday', backref='user', lazy='dynamic') class Ticketholiday(db.Model): __tablename__ = 'ticketholidays' id = db.Column(db.Integer, primary_key=True) type = db.Column(db.Integer) about = db.Column(db.Text) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
注意你在Role數據庫模型中的users,它並不是roles表中的字段,users = db.relationship('User', backref='role', lazy='dynamic'),relationship的第一個參數表示這個關系的另一個數據庫模型是哪個,這里是User,第二個參數backref表示給關聯的數據庫模型添加一個屬性,這里是role。
也就是說,你可以通過User模型的role這個屬性去訪問Role模型,比如你在views.py中的查詢結果,你可以通過user.role.name得到roles表中對應記錄的name,user.role.id則得到roles表中對應記錄的id
注意名稱的大小寫,一一對應