在 Postgres 上使用 sqlalchemy 创建部分唯一索引
Creating partial unique index with sqlalchemy on Postgres
SQLAlchemy 支持创建 partial indexes in postgresql.
是否可以通过 SQLAlchemy 创建 partial unique index?
想象一个 table/model 是这样的:
class ScheduledPayment(Base):
invoice_id = Column(Integer)
is_canceled = Column(Boolean, default=False)
我想要一个唯一索引,其中对于给定发票只能有一个 "active" ScheduledPayment。
我可以在 postgres 中手动创建这个:
CREATE UNIQUE INDEX only_one_active_invoice on scheduled_payment
(invoice_id, is_canceled) where not is_canceled;
我想知道如何使用 SQLAlchemy 0.9 将其添加到我的 SQLAlchemy 模型中。
class ScheduledPayment(Base):
id = Column(Integer, primary_key=True)
invoice_id = Column(Integer)
is_canceled = Column(Boolean, default=False)
__table_args__ = (
Index('only_one_active_invoice', invoice_id, is_canceled,
unique=True,
postgresql_where=(~is_canceled)),
)
万一有人想用一个可以选择 NULL
的列设置部分唯一约束,方法如下:
__table_args__ = (
db.Index(
'uk_providers_name_category',
'name', 'category',
unique=True,
postgresql_where=(user_id.is_(None))),
db.Index(
'uk_providers_name_category_user_id',
'name', 'category', 'user_id',
unique=True,
postgresql_where=(user_id.isnot(None))),
)
其中 user_id
是一个可以是 NULL
的列,我希望在所有三列 (name, category, user_id)
中强制执行唯一约束,其中 NULL
只是允许的列之一user_id
.
的值
补充一下 sas 的答案,postgresql_where 似乎不能接受多个布尔值。因此,在您有两个 null-able 列的情况下(假设有一个额外的 'price' 列),不可能有四个部分索引用于 NULL/~NULL 的所有组合。
一种解决方法是使用永远不会是 'valid' 的默认值(例如,-1 表示价格或 '' 表示文本列。它们可以正确比较,因此不允许超过一行具有这些默认值。
显然,您还需要在所有现有数据行中插入此默认值(如果适用)。
SQLAlchemy 支持创建 partial indexes in postgresql.
是否可以通过 SQLAlchemy 创建 partial unique index?
想象一个 table/model 是这样的:
class ScheduledPayment(Base):
invoice_id = Column(Integer)
is_canceled = Column(Boolean, default=False)
我想要一个唯一索引,其中对于给定发票只能有一个 "active" ScheduledPayment。
我可以在 postgres 中手动创建这个:
CREATE UNIQUE INDEX only_one_active_invoice on scheduled_payment
(invoice_id, is_canceled) where not is_canceled;
我想知道如何使用 SQLAlchemy 0.9 将其添加到我的 SQLAlchemy 模型中。
class ScheduledPayment(Base):
id = Column(Integer, primary_key=True)
invoice_id = Column(Integer)
is_canceled = Column(Boolean, default=False)
__table_args__ = (
Index('only_one_active_invoice', invoice_id, is_canceled,
unique=True,
postgresql_where=(~is_canceled)),
)
万一有人想用一个可以选择 NULL
的列设置部分唯一约束,方法如下:
__table_args__ = (
db.Index(
'uk_providers_name_category',
'name', 'category',
unique=True,
postgresql_where=(user_id.is_(None))),
db.Index(
'uk_providers_name_category_user_id',
'name', 'category', 'user_id',
unique=True,
postgresql_where=(user_id.isnot(None))),
)
其中 user_id
是一个可以是 NULL
的列,我希望在所有三列 (name, category, user_id)
中强制执行唯一约束,其中 NULL
只是允许的列之一user_id
.
补充一下 sas 的答案,postgresql_where 似乎不能接受多个布尔值。因此,在您有两个 null-able 列的情况下(假设有一个额外的 'price' 列),不可能有四个部分索引用于 NULL/~NULL 的所有组合。
一种解决方法是使用永远不会是 'valid' 的默认值(例如,-1 表示价格或 '' 表示文本列。它们可以正确比较,因此不允许超过一行具有这些默认值。
显然,您还需要在所有现有数据行中插入此默认值(如果适用)。