在 Django 中为 Postgres 存储生成的列创建 Gin 索引

Creating Gin index for Postgres stored generated column in Django

我想设置一个 Postgres "stored generated columns" with indexing to have full text search on two fields of a model. I created the generated column getting help from this tutorial,但是在列上设置 gin 索引时,我得到这个:

django.core.exceptions.FieldDoesNotExist: Article has no field named 'vector_column'. The app cache isn't ready yet, so if this is an auto-created related field, it won't be available yet.

这是我的 Article 模型:

class Article(models.Model):
    title = models.CharField(...)
    content = models.TextField(...)
    class Meta:
        indexes = [GinIndex(fields=['vector_column'])]

和我在迁移文件中的自定义 sql:

    operations = [
        migrations.RunSQL(
            sql='''
              ALTER TABLE articles_article ADD COLUMN vector_column tsvector GENERATED ALWAYS AS (
                setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
                setweight(to_tsvector('english', coalesce(content,'')), 'B')
              ) STORED;
            ''',

            reverse_sql='''
              ALTER TABLE articles_article DROP COLUMN vector_column;
            '''
        ),
    ]

是否可以从 Django 设置索引?似乎 Django 需要在模型上定义字段,但这不是生成列的工作方式。如果不是,那么在迁移文件中设置正确索引的正确方法是什么(在此 Postgres doc 中提到,页面末尾的索引)?

正如 Iain 在评论中所说,索引必须在迁移中处理。我刚刚向 operations 数组添加了另一个迁移:

    operations = [
        migrations.RunSQL(
            sql='''
              ALTER TABLE articles_article ADD COLUMN vector_column tsvector GENERATED ALWAYS AS (
                setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
                setweight(to_tsvector('english', coalesce(content,'')), 'B')
              ) STORED;
            ''',

            reverse_sql='''
              ALTER TABLE articles_article DROP COLUMN vector_column;
            '''
        ),
        migrations.RunSQL(
            sql='''
                CREATE INDEX textsearch_idx ON articles_article USING GIN (vector_column);
            ''',

            reverse_sql='''
                DROP INDEX IF EXISTS textsearch_idx;
            '''
        ),
    ]