SQLAlchemy 在声明性表上的多对多关系

10 投票
1 回答
6177 浏览
提问于 2025-04-16 00:48

我有以下这些表格,它们是以声明的方式定义的(这是一个非常简化的版本):

class Profile(Base):
        __tablename__ = 'profile'

        id = Column(Integer, primary_key = True)
        name = Column(String(65), nullable = False)

        def __init__(self, name):
            self.name = name


class Question(Base):
    __tablename__ = 'question'

    id = Column(Integer, primary_key = True)
    description = Column(String(255), nullable = False)
    number = Column(Integer, nullable = False, unique = True)


    def __init__(self, description, number):
        self.description = description
        self.number = number



class Answer(Base):
    __tablename__ = 'answer'

    profile_id = Column(Integer, ForeignKey('profile.id'), primary_key = True)
    question_id = Column(Integer, ForeignKey('question.id'), primary_key = True)
    value = Column(Integer, nullable = False)


    def __init__(self, profile_id, question_id, value):
        self.profile_id = profile_id
        self.question_id = question_id
        self.value = value

Profile(个人资料)和Question(问题)之间是多对多的关系。也就是说,一个个人资料可以关联多个问题,而一个问题也可以被多个个人资料关联。在这个连接表(Answer,答案)中,我需要存储一个关于答案的值。

文档上说我需要使用一个关联对象来实现这个功能,但这让我感到困惑,我也搞不定它。

我该如何使用Answer作为中介表来定义Profile和Question表之间的多对多关系呢?

1 个回答

13

文档上说我需要使用一个关联对象来实现这个功能,但这让我感到困惑,我无法让它正常工作。

没错。Answer类就是你的关联对象,它对应着名为'answer'的关联表。

我该如何定义Profile和Question表之间的多对多关系,使用Answer作为中介表呢?

你在问题中提供的代码是正确的。它只需要在ORM层面上添加一些关于关系的额外信息:

from sqlalchemy.orm import relationship

...

class Profile(Base):
    __tablename__ = 'profile'

    ...

    answers = relationship("Answer", backref="profile")

    ...


class Question(Base):
    __tablename__ = 'question'

    ...

    answers = relationship("Answer", backref="question")

    ...

另外,你不应该在Answer的初始化函数中设置profile_id和question_id的值,因为这些值是由ORM根据你对对象关系属性的赋值来自动设置的。

你可能会对阅读声明式文档感兴趣,特别是关于配置关系的部分。了解处理相关对象的内容也可能会对你有帮助。

撰写回答