将一个SQLAlchemy模型定义为与多个其他模型之一相关

时间:2016-09-24 14:50:48

标签: python sqlalchemy

我正在为自己的Q& A网站设计数据库,这有点类似于Stack Overflow:

  1. “问题”可以有几个“答案”,但“答案”只有一个“问题”。
  2. “问题”和“答案”都可以有多个“评论”,但“评论”只有一个“问题”或“答案”。
  3. 我不知道如何设计这样的数据库。这是我尝试过的:

    class Question(db.Model):
        __tablename__ = 'questions'
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.Unicode(64), unique=True)
        body = db.Column(db.UnicodeText)
        author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
        answers = db.relationship('Answer', backref='question', lazy='dynamic')
    
    class Answer(db.Model):
        __tablename__ = 'answers'
        id = db.Column(db.Integer, primary_key=True)
        body = db.Column(db.UnicodeText)
        author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
        question_id = db.Column(db.Integer, db.ForeignKey('questions.id'))
    
    class Comment(db.Model):
        __tablename__ = 'comments'
        id = db.Column(db.Integer, primary_key=True)
        # post_id = db.Column(db.Integer, db.ForeignKey('')) ???
    

2 个答案:

答案 0 :(得分:3)

所以你已经掌握了第一点。

您正在寻找的是一种通用关系。您可以在sqlalchemy_utils包中找到它。

from sqlalchemy_utils import generic_relationship


class Comment(db.Model):
    __tablename__ = 'comments'
    id = db.Column(db.Integer, primary_key=True)
    object_type = db.Column(db.Unicode(255))
    object_id = db.Column(db.Integer)
    object = generic_relationship(object_type, object_id)

Docs用于通用关系

基本上它的作用是,它将object_type存储为答案或问题,并将object_id存储为对象的主键。

答案 1 :(得分:3)

我建议您提取问答的基类,例如:发布,并使评论与帖子相关,这样帖子可以有多个评论。

SQLAlchemy ORM支持少量this question策略,选择正确的策略取决于您计划查询实体的方式。这是implement inheritance in the database

所以你会得到这样的东西:

(免责声明:我没有直接运行此代码,但是根据您的示例和我自己的代码编写它。如果它不适合您,请告诉我,我会修复)

class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True)
    kind = Column(db.Unicode(64), nullable=False)
    body = db.Column(db.UnicodeText)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    comments = db.relationship('Comment', backref='post', lazy='dynamic')

    __mapper_args__ = {
        'polymorphic_identity': 'posts',
        'polymorphic_on': kind
    }

class Question(Post):
    __tablename__ = 'questions'

    title = db.Column(db.Unicode(64), unique=True)
    answers = db.relationship('Answer', backref='question', lazy='dynamic')

    __mapper_args__ = {
        'polymorphic_identity': 'questions',
    }

class Answer(Post):
    __tablename__ = 'answers'

    question_id = db.Column(db.Integer, db.ForeignKey('questions.id'))

    __mapper_args__ = {
        'polymorphic_identity': 'answers',
    }

class Comment(db.Model):
    __tablename__ = 'comments'

    id = db.Column(db.Integer, primary_key=True)
    post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))