Как инкрементально добавить лексему/s к существующему значению документа Django SearchVectorField через ORM?

Вы можете добавить к существующему значению Postgresql tsvector с помощью ||, например:

UPDATE acme_table 
SET _search = 
    _search || to_tsvector('english', 'some new words to add to existing ones') 
WHERE id = 1234;

Есть ли способ получить доступ к этой функциональности через Django ORM? Т.е. инкрементально добавить к существующему значению SearchVectorField, а не перестраивать с нуля?

Проблема в том, что свойство SearchVectorField возвращает tsvector в виде строки. Поэтому, когда я использую оператор || как +, например:

from django.contrib.postgres.search import SearchVector

instance.my_tsvector_prop += SearchVector(["new", "words"], weight="A", config='english')

Я получаю ошибку:

TypeError: SearchVector can only be combined with other SearchVector instances, got str.

Причина:

type(instance.my_tsvector_prop) == str

Исправление этой открытой ошибки в Django, когда свойство SearchVectorField возвращает экземпляр SearchVector, вероятно, позволило бы это сделать, если это возможно. (Хотя это менее эффективно, чем объединение в базе данных. Это обновление будет выполняться асинхронно, поэтому производительность не слишком важна.)

MyModel.objects
    .filter(pk=1234)
    .update(my_tsvector_prop=
        F("my_tsvector_prop") + 
        SearchVector(
            ["new_field_name"], 
            weight="A", 
            config='english')
        )

Возвращается:

FieldError: Cannot resolve expression type, unknown output_field

Другим решением может быть выполнение необработанного SQL UPDATE, хотя я бы предпочел сделать это через Django ORM, если это возможно, поскольку наши поля tsvector часто ссылаются на значения во многих джойнах, поэтому было бы неплохо найти устойчивое решение.

Вернуться на верх