2012-06-23 28 views
9

我使用flask-sqlalchemy建立一個web應用程序,我有以下模式(S):組合鍵在SQLAlchemy的

class Post(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(80), unique=True) 
    candidates = db.relationship('Candidate', backref='post', lazy='dynamic') 

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

    def __repr__(self): 
     return "<Post %r>" % self.name 

class Candidate(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(80), primary_key=True) 
    post_id = db.Column(db.Integer, db.ForeignKey('post.id')) 
    hostel = db.Column(db.String(80)) 
    yes_no = db.Column(db.Boolean) 
    #votes = db.relationship('Vote', backref='vote', lazy="dynamic") 

    def __init__(self, name, hostel, post_id, yes_no): 
     self.name = name 
     self.hostel = hostel 
     self.post_id = post_id 
     self.yes_no = yes_no 

    def __repr__(self): 
     return "<Candidate: %r, Post: %r>" % (self.name, self.post.name) 

我完全的noob當涉及到數據庫的設計,所以我真的欣賞我關於一些基本查詢的幾點指示

  • 是否需要id這一列?我見過的大多數教程都將其作爲一個專欄(主鍵)。我可以沒有它嗎?特別是在我有另一個主鍵的情況下?

  • 假如post_id是外鍵,我如何在Candidate#Name和Candidate#post_id列上有複合鍵約束。

  • 如何「刷新」我的數據庫。在對模型進行了修改之後,如何確保這些更改反映在實際的表中?手動需要drop_allcreate_all嗎?

  • 最後,sqlalchemy文檔是否也適用於flask-sqlalchemy

+2

您可能需要打出這些問題;當您在一個問題中發佈多個問題時,您正在讓人們難以向您提供答案。所有'sqlalchemy'文檔也適用於'flask-sqlalchemy'。 –

回答

20

是ID列有必要嗎?我見過的大多數教程都將其作爲一個專欄(主鍵)。我可以沒有它嗎?特別是在我有另一個主鍵的情況下?

對於張貼表,是的。對於另一個,沒有。有人可能會爭辯說,因爲名字是獨一無二的,所以將它作爲主鍵,但這意味着使用任何地方的名稱您需要引用該帖子,這意味着更多的空間(名稱長度與int)(不一定是問題)並考慮「如果候選人姓名改變了怎麼辦?」。但是,你當然不需要兩者。

假如post_id是外鍵,我如何在Candidate#Name和Candidate#post_id列上有複合鍵約束。

你是如何做的,每一個崗位被分配到一個單一的差價:

candidates = db.relationship('Candidate', backref='post', lazy='dynamic') 

因此,該領域不應該叫candidatescandidate是有道理的。

要回答你的問題,我會從the docs引用:

要在約束/索引指定多個列或指定一個 明確的名稱,使用的UniqueConstraint或指數構建 明確。

您將需要添加到您的模型定義:

__table_args__ = (
     UniqueConstraint("id", "candidate_id"), 
    ) 

雖然我認爲這是沒用這裏(你爲什麼需要它,如果ID是唯一的(主鍵),那麼任何其他組合包含它將是唯一的)...

如何「刷新」我的數據庫。我在模型中進行了更改後,如何確保這些更改反映在實際表格中? 我需要手動drop_all和create_all嗎?

您需要將commit更改爲數據庫。從flask-sqlalchemy's documentation

db.session.add(post) 
db.session.commit() 

最後,請問SQLAlchemy的文檔,適用於燒瓶SQLAlchemy的爲 呢?

注意這是我發現我自己,沒有「官方」源,通過閱讀燒瓶SQLAlchemy的的來源。

是的,有什麼不同,就是你訪問模型和會話以及發動機和方式... 例如,在SQLAlchemy的:

from sqlalchemy.orm import sessionmaker 
Session = sessionmaker() 
session = session() 
session.commit() 

而在燒瓶的SQLAlchemy:

db.session.commit() 

而對於 「模式」:

# In sqlalchemy 
Base = declarative_base() 
class Post(Base): 
    # ... 

# In flask-sqlalchemy 
class Post(db.Model): 
    # ... 

等等

無論如何,你在sqlalchemy的方式做了什麼,你做了一次,而flask-sqlalchemy在後臺爲你做。

希望它能幫助:)(這就是很多關於SQLAlchemy的複合鍵不止一個問題...)

+0

soooo ...你如何添加複合鍵? –

+0

@PiotrKamoda如果您需要複合主鍵,只需將'primary_key = True'設置爲所有主鍵字段。或者在'__table_args__'中使用類似'UniqueConstraint(「id」,「candidate_id」)'的東西。您甚至可以在表格參數中指定更復雜的主鍵。 – jadkik94