【问题标题】:Can you achieve a case insensitive 'unique' constraint in Sqlite3 (with Django)?你能在 Sqlite3(使用 Django)中实现不区分大小写的“唯一”约束吗?
【发布时间】:2010-09-21 13:22:33
【问题描述】:

假设我正在使用 Python 2.5 的内置默认 sqlite3,并且我有一个带有以下代码的 Django 模型类:

class SomeEntity(models.Model):
    some_field = models.CharField(max_length=50, db_index=True, unique=True)

我已经设置了管理界面,一切似乎都工作正常,除了我可以创建两条 SomeEntity 记录,一条带有 some_field='some value' 和一条带有 some_field='Some Value' 因为 some_field 的唯一约束似乎区分大小写。

有没有办法强制 sqlite 在检查唯一性时执行区分大小写的比较

我似乎在 Django 的文档中找不到这个选项,我想知道是否有什么可以直接对 sqlite 做的事情,让它按照我想要的方式运行。 :-)

【问题讨论】:

  • 为了避免重复答案,也许this answer可以让你走上正轨?

标签: python django sqlite django-models


【解决方案1】:

是的,这可以通过使用以下命令向表中添加唯一索引来轻松完成:

在 mytable(myfield COLLATE NOCASE)上创建唯一索引 uidxName

如果您需要对非 ASCII 字母不区分大小写,则需要使用类似于以下的命令注册自己的 COLLATION:

以下示例显示了一个按“错误方式”排序的自定义排序规则:

import sqlite3

def collate_reverse(string1, string2):
    return -cmp(string1, string2)

con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)

cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
    print row
con.close()

显示的 sqlite3 的其他 python 文档here

【讨论】:

    【解决方案2】:

    也许您可以创建和使用自定义模型字段;它将是 CharField 的子类,但提供了一个 db_type 方法返回“text collat​​e nocase”

    【讨论】:

    • 有趣,但 COLLATE NOCASE 仅对 ASCII 字母不区分大小写。无论如何,我只是将 sqlite 用于原型,而不是最终产品。不过感谢您的建议。
    【解决方案3】:

    对于 2021 年的任何人,在 Django 4.0 UniqueConstraint expressions 的帮助下,您可以像这样将 Meta 类添加到您的模型中:

    class Meta:
        constraints = [
            models.UniqueConstraint(
                Lower('<field name>'),
                name='<constraint name>'
            ),
        ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-25
      • 2013-05-30
      • 2013-05-11
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多