在 SQLAlchemy 中对多列创建约束

时间:2021-01-25 10:54:07

标签: python mysql flask-sqlalchemy

我有一个 MySQL 表,用于管理由以下模型描述的城市中的建筑物入口方法:

class EntranceMethod(db.Model):
    id = Column(String, primary_key=True)
    building_id = ForeignKey('building.id', nullable=False)
    user_id = ForeignKey('user.id', nullable=False)
    card_name = Column(String, nullable=False)
    gate = Column(Enum('A', 'B', 'C'), nullable=False) 

在一座建筑物中,一个人可以拥有许多卡片,这些卡片可以用来识别他们并允许他们通过某些门。但是,这些卡片也可用于在其他建筑物中执行此操作。

在建筑范围内,我想确保:

  • 对于特定的门,用户不能使用超过 1 张卡进入。 (他们可以通过此卡进入其他门的建筑物,但不能在此门使用其他卡)。

所以我创建了一个唯一约束:(building_id, user_id, gate)

  • 一张卡只属于 1 个用户。

我应该做什么样的约束?我想到了对 building_id, card_name, gate 的唯一约束可以解决问题,但它只是说,'这张卡每个只能由一个用户使用门'。用户U在A门使用卡K,用户V在B门使用卡K的情况仍然可以。

例如,我有一些记录(一个建筑范围):

<头>
user_id card_name
user1 card1-1 A
user1 card1-2 B
user2 card2-1 C
user2 card1-1 B

唯一约束 (building, user_id, gate) 已满足,但名为 card1-1 的卡片属于 2 个用户。

1 个答案:

答案 0 :(得分:1)

您的约束 (building_id, user_id, gate) 暗示给定用户的入口方法的唯一性。 口头上,这意味着

“一个用户不能有多个进入建筑物大门的方法”

“建筑物中的一个门不能有超过 1 个进入单个用户的方式”

由于您没有以任何方式处理卡片的唯一性,因此不可能暗示 User1User2 的卡片不同。但是,您的主要条件仍然会得到满足 - 一个用户将只能使用一张卡片(无论您将放入 cardEntranceMethod 字段中的任何文本)通过。

由于每个用户只有一种入口方法,因此对于给定的 cardUserbuilding_id,不会有重复的 gate 字段。

如果您还想确保用户不会共享他们的卡片进入,您可以引入一个 Card 模型,从 ForeignKeyUser 模型。这样,一个卡片实例将只附加到一个 User

但是,此方法意味着您必须在创建时验证 EntranceMethod - 另外检查 card_id 是否是用户的卡片之一。

相关问题