### **關聯關系定義**
* `relationship`的幾個常用的參數
* `backref`:是在一對多或者多對一關系之間簡歷雙向的關系
* `lazy`:懶加載,默認為`True`
* `remote_side`: 外鍵是自身時使用,例如`remote_side=[id]`
* `secondary`:指向多對多的中間表
<br/>
### **一對多/多對一**
~~~
class User(Base):
__tablename__ = 'users'
id= Column(Integer, primary_key=True)
posts = relationship('Post', backref='post')
class Post(Base):
__tablename__ = 'posts'
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship('User', back_populates='posts', cascade='all, delete, delete-orphan')
// back_populates屬性為反向關系所對應的屬性進行命名,其值應該是User里面定義的屬性名稱,
// cascade屬性是一個觸發器,表示當刪除user的時候,與其關聯的posts會自動同時刪除,
// 但無論怎樣,我更建議自己手動去刪除
user = User(...)
user.posts = [ # 創建相關聯的對象,不需要指定user_id了
Post(...), Post(...)
]
user.posts # 獲取所關聯的posts
post.user # 獲取所關聯的user
session.commit() # 提交創建user和posts
~~~
<br/>
### **一對一**
僅需要將上面的一對多關系中`uselist=False`即可
~~~
class User(Base):
__tablename__ = 'users'
posts = relationship('Post', uselist=False, back_populates='post')
~~~
### **多對多**
* 關于一個表同一個字段對應多張表的外鍵(類似`Laravel/Django`中的`target_id/targe_type`定義方式),
`sqlalchemy`沒有一個官方的定義方式,有個現成的[Generic relationships](https://sqlalchemy-utils.readthedocs.io/en/latest/generic_relationship.html),但是該庫作者已經許久沒維護了。我的建議是自己join吧。
* 如上一條`SQlAlchemy`里面比較難實現復雜的多對多關系,所以官方的文檔就干脆建議大家連關系表都不用單獨建daemon了,直接按照下面的方法來更簡單。
~~~
// 一個用戶對應多個權限,一個權限對應多個用戶
user_privilege_relationship = Table('user_privilge_relationships', Base.metadata,
Column('user_id', Integer, ForeignKey('users.id'))
Column('privilege_id', Integer, ForeignKey('privilege.id'))
)
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
privileges = relationship('Privilege', secondary=user_privilege_relationship, backref='users')
class Privilege(Base)
__tablename__ = 'privileges'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary=user_privilege_relationship, backref='privileges')
~~~