Question

I am having a problem with constraints with SQLAlchemy in my Pyramid web application with PostgreSQL.

I have an object which can be in different states:

class Foo(Base):

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

Now I want to always have only one (or none) object in active state, only one (or none) object in next state, and there should be no limits on how many objects are in other two states.

I want to make a constraint or something that acts as a constraint that will not allow changing any other object's state to active state if there is already an object in that state (and same for next state).

Unique constraint won't do the trick here as I only want some values to be unique and not all of them. Basically all I want is that whenever I commit a transaction, there is a mechanism that doesn't allow transaction to get committed if it would break the constraint that i wrote about. How can I do that?

Was it helpful?

Solution

PostgreSQL supports this with partial unique indexes.

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');

will constrain the table such that only one row may have state 'active' or 'next'. You can use a single index with state IN ('active', 'next') if you prefer, but I think this form is more likely to actually get used in queries for state = 'active' or state = 'next'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top