2014-02-28 34 views
2

我在使用PostgreSQL的金字塔Web應用程序中使用SQLAlchemy的約束問題。用於更新表的SQLAlchemy自定義約束條件

我有一個對象,它可以在不同的狀態:

class Foo(Base): 

    # -1 - inactive 
    # 0 - in queue 
    # 1 - next 
    # 2 - active 
    state = Column(
     Integer, 
     nullable=False 
    ) 

現在我要永遠只有一個(或無)處於激活狀態的對象,在接下來的狀態只有一個(或無)對象,對於其他兩種狀態下有多少個對象應該沒有限制。

我想要充當一個約束,將不允許改變任何其他對象的狀態到激活狀態,如果已經有在該狀態的對象(與同爲下一個狀態)的約束或東西。

獨特的約束不會在這裏做的伎倆,因爲我只想要一些值是唯一的,而不是全部。 基本上所有我想要的是,只要我提交一個事務,就有一種機制不允許事務被提交,如果它會打破我寫的約束。 我該怎麼做?

+0

是的,當然。我基本上有一個任務正在進行,一個任務總是處於就緒狀態(下一步)。當任務處於活動狀態,不同的用戶可以從活動中刪除它,把下一個任務處於活動狀態和新的任務準備狀態。問題發生,如果多個用戶做到這一點的同時,這就是爲什麼我需要這樣的約束。 – ferewuz

回答

4

PostgreSQL支持部分唯一索引。

CREATE UNIQUE INDEX foo_only_one_active ON foo(state) WHERE (state = 'active'); 

CREATE UNIQUE INDEX foo_only_one_active ON foo(state) WHERE (state = 'next'); 

將約束該表,使得只有一行可能具有「活動」或「下一個」狀態。您可以使用一個索引與state IN ('active', 'next')如果你喜歡,但我覺得這種形式更可能實際上是在查詢得到用於state = 'active'state = 'next」。

+0

謝謝!這似乎是訣竅!我只是在看SQLAlchemy的鹼溶液中,並沒有深入到PostgreSQL的一部分:) – ferewuz