Можете ли вы добиться нечувствительного к регистру "уникального" ограничения в Sqlite3 (с Django)?

Итак, скажем, я использую встроенный sqlite3 по умолчанию для Python 2.5, и у меня есть класс модели Django со следующим кодом:

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

У меня есть настройка интерфейса администратора, и все работает отлично, за исключением того, что я могу создать две записи SomeEntity, одну с some_field = 'some value' и one with some_field = 'Some Value', потому что уникальное ограничение на some_field представляется чувствительным к регистру.

Есть ли способ заставить sqlite выполнять нечувствительное к регистру сравнение при проверке уникальности?

Я не могу найти вариант для этого в документах Django, и мне интересно, есть ли что-то, что я могу сделать непосредственно для sqlite, чтобы заставить его вести себя так, как я хочу.: -)

Ответ 1

Да, это легко сделать, добавив уникальный индекс в таблицу со следующей командой:

CREATE UNIQUE INDEX uidxName ON mytable (myfield COLLATE NOCASE)

Если вам нужна нечувствительность к регистру для букв nonASCII, вам нужно будет зарегистрировать собственное 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()

Дополнительная документация на python для sqlite3 показана здесь

Ответ 2

Возможно, вы можете создать и использовать поле настраиваемой модели; это был бы подкласс CharField, но предоставляющий db_type метод, возвращающий "text collate nocase"