【问题标题】:How to prevent IntegrityError in case of using UUID in django在 django 中使用 UUID 时如何防止 IntegrityError
【发布时间】:2025-12-16 12:25:03
【问题描述】:

我想在我的 django 模型中使用 UUID 作为 PK 如下(数据库是 Postgresql):

class Post(models.Model):
    pk = models.UUID(primary_key=True, unique=True, default=uuid.uuid4, editable=False)
    ...

每次uuid.uuid4 生成一个新的 UUID。
我的问题是:uuid.uuid4 是否有可能生成重复的 UUID?
如果可能的话,如果生成重复的 UUID,如何防止 IntegrityError?

【问题讨论】:

  • 看看这篇文章:Are UUIDs really unique?,你真的不需要担心,发生这种情况的可能性真的很低。
  • @AbdulAzizBarkat 是的,我知道概率很低。但我想找到一种解决方案来防止这种非常低的概率。

标签: django postgresql django-models uuid database-integrity


【解决方案1】:

确保您没有损害数据库但仍使用 UUID 作为标识符的最佳方法是执行以下操作:

# Or whatever field name suits you best / unique=True for integrity purposes
uuid_pk = models.UUID(unique=True, default=uuid.uuid4, editable=False)

只需将其设为辅助键且唯一,并照常使用 Django 提供的 pk。

【讨论】:

  • 这不是解决方案。添加unique=True 并不能解决问题。如果生成重复的 UUID,只会引发 IntegrityError,这是我遇到的主要问题。
  • UUID 默认为not guaranteed unique but practically unique,但有一种方法可以做到这一点,在保存实例时覆盖 save 方法并向 uuid 字段添加自动增量值,
【解决方案2】:

据此answer by Bob Aman

坦率地说,在单个应用程序空间中 没有恶意行为者, 地球上所有生命将灭绝 早在你有一个 碰撞,即使在版本 4 UUID 上, 即使你产生了很多 每秒 UUID。

你真的不需要担心任何重复,如果你仍然担心尝试使用 uuid1 代替,因为它使用机器 MAC 和时间戳,所以出现重复的机会更小。如果需要,您始终可以使用 try-except 块来检查 IntegrityErrors。

【讨论】: