【问题标题】:Best way to create Singleton Table in Django/MySQL在 Django/MySQL 中创建单例表的最佳方法
【发布时间】:2010-09-23 10:56:03
【问题描述】:

我想要一张只能有一条记录的表格。我目前的解决方案是:

class HitchingPost(models.Model):
    SINGLETON_CHOICES = (('S', 'Singleton'),)
    singleton = models.CharField(max_length=1, choices=SINGLETON_CHOICES, unique=True, null=False, default='S');
    value = models.IntegerField()

    def __unicode__(self):
        return u"HitchingPost" # only ever one record

这有点难看,并且不会在 MySQL 级别强制执行约束。

有没有更好的解决方案?

是否存在只能有一个值的 MySQL 字段类型(布尔值是我发现的最小的,有两种可能性)?一个基数为 0 的数字是我最接近表达这个概念的数字。

这种东西有数学名称吗?

谢谢,

克里斯。

附:生成的 SQL 是:

CREATE TABLE `appname_hitchingpost` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `singleton` varchar(1) NOT NULL UNIQUE,
    `value` integer NOT NULL
)
;

【问题讨论】:

  • ''这样的东西有数学名称吗?'' - 一个常数?
  • 它确实在 MySQL 级别强制执行约束。试试例如HitchingPost.objects.create(value=12) 后跟例如HitchingPost.objects.create(value=13)。如果你没有得到 IntegrityError,那么你有一些更广泛的问题。
  • @Tomasz - 是的,它在 Django 层强制执行完整性,但 MySQL 表没有类似的约束。非 Django 应用程序可以毫无问题地插入 value=13。如果你有兴趣,我会挖掘它创建的 SQL。
  • Django 本身并不强制执行 UNIQUE 约束,它是由 MySQL 完成的。因此,如果 MySQL 不抱怨手动添加其他记录,那么我猜这是因为它们包含 singleton=NULL 并且由于某种原因 singleton 字段的定义不包含 NOT NULL ingridient (您是否手动创建了该表,而不是使用./manage.py syncdb ?)
  • @Tomasz - 抱歉,我的论点不完整。我应该说的是,非 Django 应用程序可以插入 value=13,前提是它为单例字段提供了不同的(即非“S”)值。 Django 不会为单例字段创建单值 MySQL 枚举。我已经修改了原始问题以显示生成的 SQL。

标签: python mysql django django-models


【解决方案1】:

这有点难看,并且不会在 MySQL 级别强制执行约束。

如果您担心强制执行,您应该查看 Django 的 model validation 方法。你可以编写一个自定义的validate_unique,如果HitchingPost.objects.count() != 0 将引发ValidationError

class HitchingPost(models.Model):
    ...
    def validate_unique(self, exclude = None):
        from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
        if HitchingPost.objects.count() != 0:
            raise ValidationError({NON_FIELD_ERRORS: ["There can be only one!"]})

有没有更好的解决方案?

如果不进一步了解您更广泛的要求,很难说。

是否存在只能有一个值的 MySQL 字段类型(布尔值是我发现的最小的,有两种可能性)?以 0 为底的数字是我最接近表达概念的数字。

您可以尝试自定义单个元素enum。我从来没有尝试过这样的事情,所以请接受我的建议。

这种东西有数学名称吗?

Set-once-constant?我编的。事实上,我不知道。这里有更好的人会帮助你。

【讨论】:

  • 我刚刚实施了那个解决方案,它运行得非常好,谢谢!我唯一要添加的是,您可以允许创建和更新第一个模型,同时在保存模型时检查模型上是否缺少主键:if not self.pk and HitchingPost.objects.count() > 0: ...
  • if HitchingPost.objects.exclude(id=self.id).count() > 0: 允许更新自我。
猜你喜欢
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 2013-02-19
  • 2015-06-10
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多