【发布时间】:2020-11-21 00:14:33
【问题描述】:
我有一个带有部分唯一约束的表,其中一个 cosuser_id 只能将一个 is_primary 标志设置为 True。
我想要实现的行为是:当我插入一行 is_primary=True 和一个在数据库中已经将 is_primary 标志设置为 True 的 customer_id 时,我想将该旧条目设置为 is_primary=False ,并且新条目将以 is_primary=True 插入,而不是引发 IntegrityError。
我正在使用带有 postgresql 数据库的 flask-sqlalchemy,是否有任何机制可以轻松执行此操作,或者我需要手动执行此操作,首先更新旧条目,然后插入新行?
class Customer_address(db.Model):
customer_id = db.Column(None, db.ForeignKey('customer.id'), nullable=False)
is_primary = db.Column(db.Boolean, nullable=False)
__table_args__ = (
Index(
'only_one_primary_address', # Index name
'customer_id', # Columns which are part of the index
unique=True,
postgresql_where=(is_primary) # The condition
),)
【问题讨论】:
-
我认为您需要手动重置当前主记录上的
is_primary。我认为没有办法在单个操作中使用ON CONFLICT更新现有记录和插入。 -
@snakecharmerb - 桌面上的触发器是一个可能的解决方案吗?
-
是的,
ON CONFLICT的重点是要么做一个INSERT要么一个UPDATE或者什么都不做。它不会同时执行两个操作。我相信可以使用BEFORE INSERT触发器。基本上用is_primary = 't'测试一个现有的customer_id记录是否存在,UPDATE到'f'然后通过NEW记录。这需要一些测试。相同的过程可以在应用程序的触发函数之外完成。
标签: python postgresql sqlalchemy