Как создать индекс на вычисляемых полях в peewee - PullRequest
0 голосов
/ 03 октября 2018

У меня есть следующая модель peewee (упрощенно):

class Foo(BaseModel):
    a = IntegerField() # actually a ForeignKey
    b = IntegerField(null=True) # ForeignKey
    c = IntegerField(null=True) # ForeignKey
    d = TextField()
    e = TextField(null=True)

Я хочу создать уникальный индекс для полей (a, b, c, d), считая значения NULL равными.Например, должна быть возможность вставить (1, NULL, NULL, 2, NULL) только один раз.

Мне удалось написать необработанный SQL-запрос для добавления индекса (-1 должно быть безопасно, так как b и cесть внешние ключи для int> 0)

CapsuleTranslatorBundle.add_index(SQL('''CREATE UNIQUE INDEX foo_idx ON foo (
    a, # a_id if a is a foreign key
    COALESCE(b, -1),
    COALESCE(c, -1),
    d
);
'''))

Я пытался

idx = Foo.index(Foo.a,
                fn.COALESCE(Foo.b, -1),
                fn.COALESCE(Foo.c, -1),
                Foo.d, unique=True)
Foo.add_index(idx)

, но получил

peewee.OperationalError: near "USING": syntax error

Как добавить индекс без использования необработанного SQL?

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я только что закончил анализ кода сам.Это была ошибка, уже подтвержденная и исправленная @coleifer в репозитории - спасибо!

Вот быстрое исправление, которое выдает действительный SQL (для sqlite3) на peewee 3.7.0 (может пригодиться доисправлен фиксированный код):

idx = Foo.index(Foo.a,
                Value(fn.COALESCE(Foo.b, SQL('-1'))),
                Value(fn.COALESCE(Foo.c, SQL('-1'))),
                Foo.d, unique=True)
Foo.add_index(idx)

производит

('CREATE UNIQUE INDEX IF NOT EXISTS "foo_a_d" ON "foo" ("a", COALESCE("b", -1), COALESCE("c", -1), "d")', [])

Без SQL('-1') (при использовании только -1) я получаю еще одну ошибку peewee.OperationalError: parameters prohibited in index expressions и сгенерированныйзапрос: 'CREATE UNIQUE INDEX IF NOT EXISTS "foo_a_d" ON "foo" ("a", COALESCE("b", ?), COALESCE("c", ?), "d")', [-1, -1]

0 голосов
/ 04 октября 2018

Существует ошибка, из-за которой объект функции интерпретируется неправильно из-за некоторого кода глубоко в конструкции ModelIndex.

Исправлено здесь:

...