如何使用 SQLAlchemy 创建多对多关系?

How can I create a many to many relationship using SQLAlchemy?

如何使用以下模型创建多对多关系:

class Association(Base):
    a_id = Column(BigInteger, ForeignKey('a.id'), index=True)
    b_id = Column(String, ForeignKey('b.some_other_id'))

class A(Base):
     id = Column(BigInteger, primary_key=True)

class B(Base):
     id = Column(BigInteger, primary_key=True)
     some_other_id = Column(String(100), index=True, unique=True)

使用 sqlalchemy.ormrelationship 函数并确保在连接中声明主键 table。

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey, BigInteger, String
from sqlalchemy.orm import relationship

Base=declarative_base()


class Association(Base):
        __tablename__='association'
        a_id = Column(BigInteger, ForeignKey('a.id'), index=True, primary_key=True)
        b_id = Column(String, ForeignKey('b.some_other_id'), primary_key=True)

class A(Base):
         __tablename__='a'
         id = Column(BigInteger, primary_key=True)
         b_ids = relationship('B', secondary=Association)

class B(Base):
         __tablename__='b'
         id = Column(BigInteger, primary_key=True)
         some_other_id = Column(String(100), index=True, unique=True)
         a_ids = relationship('A', secondary=Association)

改编自SQLAlchemy documentation:如果不需要关联的额外属性,则根本不需要关联模型:

association_table = Table('association', Base.metadata,
    Column('a_id', Integer, ForeignKey('a.id')),
    Column('b_id', Integer, ForeignKey('b.some_id'))
)

class A(Base):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)
    b_s = relationship("B",
                    secondary=association_table,
                    backref="a_s")

class B(Base):
    __tablename__ = 'b'
    some_id = Column(Integer, primary_key=True)

b.a_sA的集合,a.b_sB的集合;其中的更改将在 session.flush().

反映在数据库中

如果您 想要为每个 AB 之间的关联添加额外的属性,那么您可以使用 Association object pattern :

class Association(Base):
    __tablename__ = 'association'
    left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
    right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)
    extra_data = Column(String(50))
    child = relationship("Child")

class Parent(Base):
    __tablename__ = 'left'
    id = Column(Integer, primary_key=True)
    children = relationship("Association")

class Child(Base):
    __tablename__ = 'right'
    id = Column(Integer, primary_key=True)