2016-09-24 47 views
1

我設計的數據庫,爲我自己的Q &一個網站,這有點類似堆棧溢出:定義一個SQLAlchemy的模式可能與其他多種車型之一

  1. A「問題」可以有幾個「答案」,但一個「答案」只有一個「問題」。
  2. 「問題」和「答案」都可以有幾個「評論」,但「評論」只有一個「問題」或「答案」。

我不知道如何設計這樣的數據庫。以下是我已經試過:

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

對於一個簡單的實現,你可能會考慮讓'QuestionComment'和'AnswerComment'作爲獨立的實體,而不是將它們放入一個單一的實體。 –

+0

@GordonLinoff謝謝你的回覆。事實上,我曾考慮過這一點。或者,我可以將'Question'和'Answer'合併到'Post',它有一個名爲'is_question'的布爾字段。不過,我想找一個更「優雅」的方法。 –

+0

設計看起來相當不錯... – Bharel

回答

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作爲對象的主鍵。

3

我建議你爲問題和答案提取一個基類,例如發佈,並使評論與帖子相關,使得帖子可以具有多個評論。

SQLAlchemy ORM支持一些策略到implement inheritance in the database,正確的策略選擇取決於您計劃查詢實體的方式。這是detailed documentation on how to properly configure it

所以,你會得到這樣的:

(免責聲明:我沒有直接運行這個代碼,但是從你的例子,我自己的代碼組成的,如果它不爲你工作,讓我知道,我會解決)

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')) 
相關問題