【问题标题】:Creating Gin index for Postgres stored generated column in Django在 Django 中为 Postgres 存储生成的列创建 Gin 索引
【发布时间】:2021-12-31 17:27:52
【问题描述】:

我想设置一个带有索引的 Postgres "stored generated columns",以便在模型的两个字段上进行全文搜索。我创建了从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 中提到,页面末尾的索引)的正确方法是什么?

【问题讨论】:

  • 如果您通过迁移手动创建生成列,则无法在模型的 Meta 中定义索引,本文仅在使用 SearchVectorField 时以这种方式添加索引
  • @IainShelvington 那么我应该在迁移文件中手动创建索引吗?
  • 是的,这是向列添加索引的唯一方法,因为 Django 不知道它
  • 非常感谢您的 cmets。如果您将这些提交连同sqlreverse_sql 部分的示例一起提交,我会接受作为答案。
  • 你看到this了吗?

标签: django postgresql django-migrations


【解决方案1】:

正如 Iain 在 cmets 中所说,必须在迁移中处理索引。我刚刚向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;
            '''
        ),
    ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-12
    • 2017-10-03
    • 2018-07-21
    • 1970-01-01
    • 2017-12-02
    • 2023-04-01
    • 2019-01-29
    • 2012-01-31
    相关资源
    最近更新 更多