У меня есть следующая необработанная команда SQL, которую я выполняю в файле миграции Django. Мне нужно использовать необработанный SQL, потому что Django не поддерживает сгенерированные столбцы.

ALTER TABLE dockets_document ADD COLUMN search_vector tsvector GENERATED ALWAYS AS (
    setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
    setweight(to_tsvector('english', coalesce(f_arr2text(content),'')), 'B') ||
    setweight(jsonb_to_tsvector('english', coalesce(tables), '["all"]'), 'C')
) STORED;

В моем файле models.py есть следующее поле:

search_vector = SearchVectorField(null=True)

Эта строка запускает миграцию, которая генерирует для меня столбец, затем моя пользовательская миграция применяет SQL. Пользовательская миграция не выполняется, поскольку столбец уже создан (с соответствующим индексом), поэтому ADD COLUMN возвращает ошибку ERROR: column "search_vector" of relation "dockets_document" already exists. Я попытался использовать ALTER COLUMN вместо ADD COLUMN, но это не сработало (ERROR: syntax error at or near "tsvector").

Я попытался удалить поле из файла models.py, но тогда Django не знает, что поле существует, и не позволяет мне делать запросы к столбцу. И удалять его тоже нецелесообразно.

Как я могу вместо этого преобразовать существующий столбец null в столбец GENERATED?

0
Ilya Voytov 5 Май 2021 в 02:37

1 ответ

Лучший ответ

Вы можете использовать RunSQL и добавить state_operation как задокументировано

Аргумент state_operations позволяет вам предоставлять операции, эквивалентные SQL с точки зрения состояния проекта. Например, если вы вручную создаете столбец, вы должны передать здесь список, содержащий операцию AddField, чтобы автодетектор по-прежнему имел актуальное состояние модели.

В созданной вручную пустой миграции, созданной вручную

1
iklinac 4 Май 2021 в 23:51