### **关联关系定义**
* `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')
~~~