Constraints

Simple unique constraints

Unique constraints can be added to a single column using the unique=True argument of Column:

class Band(Table):
    name = Varchar(unique=True)

Advanced constraints

You can add powerful UNIQUE and CHECK constraints to your Table.

Unique

class piccolo.constraints.Unique(columns: list[Column | str], nulls_distinct: bool = True, name: str | None = None)

Add a unique constraint to one or more columns. For example:

from piccolo.constraints import Unique

class Album(Table):
    name = Varchar()
    band = ForeignKey(Band)

    unique_name_band = Unique([name, band])

In the above example, the database will enforce that name and band form a unique combination.

Parameters:
  • columns – The table columns that should be unique together.

  • nulls_distinct – See the Postgres docs for more information.

Check

class piccolo.constraints.Check(condition: Combinable | str, name: str | None = None)

Add a check constraint to the table. For example:

from piccolo.constraints import Check

class Ticket(Table):
    price = Decimal()

    check_price_positive = Check(price >= 0)

You can have more complex conditions. For example:

from piccolo.constraints import Check

class Ticket(Table):
    price = Decimal()

    check_price_range = Check(
        (price >= 0) & (price < 100)
    )
Parameters:
  • condition – The syntax is the same as the where clause used by most queries (e.g. select).

  • condition – The SQL expression used to make sure the data is valid (e.g. "price > 0").

  • name – The name of the constraint in the database.

How are they created?

If creating a new table using await MyTable.create_table(), then the constraints will also be created.

Also, if using auto migrations, they handle the creation and deletion of these constraints for you.

Mixins

Constraints can be added to mixin classes for reusability.