📅  最后修改于: 2023-12-03 15:05:19.677000             🧑  作者: Mango
在关系型数据库中,多对多关系经常出现。在SQLAlchemy ORM中,可以通过定义多个表之间的关系来查询连接多对多。
假设我们有三个表:users
、roles
和user_roles
。其中,users
表和roles
表是多对多关系,通过user_roles
表来连接。
具体表结构如下:
| id | name | |----|------| | 1 | Alice| | 2 | Bob | | 3 | Carol|
| id | name | |----|--------| | 1 | Admin | | 2 | Writer | | 3 | Reader |
| id | user_id | role_id | |----|---------|---------| | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 2 | 2 | | 4 | 3 | 3 |
首先,我们需要定义users
表和roles
表之间的多对多关系。
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
user_roles = Table('user_roles', Base.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('role_id', Integer, ForeignKey('roles.id'))
)
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
roles = relationship('Role', secondary=user_roles, back_populates='users')
class Role(Base):
__tablename__ = 'roles'
id = Column(Integer, primary_key=True)
name = Column(String)
users = relationship('User', secondary=user_roles, back_populates='roles')
然后,我们可以通过以下代码查询Alice的角色:
session.query(Role).join(User.roles).filter(User.name == 'Alice').all()
这里我们使用了join
来指定查询的表,使用filter
来指定查询条件,最后使用all
来查询所有结果。
返回结果如下:
- Role(id=1, name='Admin', users=[User(id=1, name='Alice', roles=[Role(id=1,name='Admin'), Role(id=2, name='Writer')])])
- Role(id=2, name='Writer', users=[User(id=1, name='Alice', roles=[Role(id=1,name='Admin'), Role(id=2, name='Writer')])])
这里我们可以看到,Alice拥有Admin和Writer两种角色。同时,我们也可以通过角色查询拥有该角色的用户,例如查询拥有Writer角色的用户:
session.query(User).join(Role.users).filter(Role.name == 'Writer').all()
返回结果如下:
- User(id=1, name='Alice', roles=[Role(id=1,name='Admin'), Role(id=2, name='Writer')])
- User(id=2, name='Bob', roles=[Role(id=2, name='Writer')])
这里我们可以看到,Alice和Bob拥有Writer角色。
通过定义多个表之间的关系,SQLAlchemy ORM可以很方便地查询连接多对多。通过这种方法,我们可以理解多对多关系,提高数据库的查询效率。