📜  sqlalchemy 查询连接多对多 - SQL (1)

📅  最后修改于: 2023-12-03 15:05:19.677000             🧑  作者: Mango

SQLAlchemy查询连接多对多 - SQL

在关系型数据库中,多对多关系经常出现。在SQLAlchemy ORM中,可以通过定义多个表之间的关系来查询连接多对多。

表结构

假设我们有三个表:usersrolesuser_roles。其中,users表和roles表是多对多关系,通过user_roles表来连接。

具体表结构如下:

users

| id | name | |----|------| | 1 | Alice| | 2 | Bob | | 3 | Carol|

roles

| id | name | |----|--------| | 1 | Admin | | 2 | Writer | | 3 | Reader |

user_roles

| 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可以很方便地查询连接多对多。通过这种方法,我们可以理解多对多关系,提高数据库的查询效率。