【问题标题】:Adding a SearchVectorField to a model in Django将 SearchVectorField 添加到 Django 中的模型
【发布时间】:2017-09-01 18:15:19
【问题描述】:

所以我正在尝试将SearchVectorField 添加到 Django 中的模型:

class JobPosting(models.Model):
    ...
    ...
    search_vector = SearchVectorField()

我知道它应该是 nullable 或具有能够迁移的默认值,因此我删除了表中的所有条目以防止出现此问题。

但是,我在运行 makemigrations 时遇到以下错误:

You are trying to add a non-`nullable` field 'search_vector' to jobposting without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
   1) Provide a one-off default now
      (will be set on all existing rows with a null value for this column)
   2) Quit, and let me add a default in models.py
Select an option:

如果表是空的,为什么会这样说?我不想使列可以为空,如果可以避免,我宁愿没有默认值。

我的问题是,有没有办法强制makemigrationsmigrate,因为如果表是空的,我不明白这个问题。我有其他表,其中包含我不想删除的数据,因此无法删除数据库中的所有信息。

或者,如果选项1) 是解决方案,我将如何格式化此类字段的默认值?我认为这不是一个普通的文本字段?

感谢您的帮助。

【问题讨论】:

    标签: python django postgresql django-models django-postgresql


    【解决方案1】:

    我不完全确定您为什么不希望有一个默认值,但我会假设这是给定的。

    我的问题是,有没有办法强制进行迁移和迁移 因为如果表是空的,我不明白问题所在。

    您的当前 数据库表可能是空的,但迁移应该可以在其他数据库实例上重复。因此 Django 不能假设在任何其他数据库上也是如此。

    解决方法可能是定义一个迁移,将字段创建为可为空,索引所有条目,然后将其更新为不可为空。

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.contrib.postgres.search import SearchVector, SearchVectorField      
    from django.db import migrations
    
    
    def index_entries(apps, schema_editor):
        Entry = apps.get_model("mymodel", "Entry")
        Entry.objects.update(search_vector=SearchVector('body_text'))
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('mymodel', '0001_initial'),
        ]
    
        operations = [
            migrations.AddField(
                model_name='entry',
                name='search_vector',
                field=SearchVectorField(null=True),
            ),
    
            migrations.RunPython(index_entries),
    
            migrations.AlterField(
                model_name='entry',
                name='search_vector',
                field=SearchVectorField(null=False),
            ),
        ]
    

    【讨论】:

    • 这个问题的答案很好,特别是涵盖表中现有数据的情况,因此不会丢失数据。这个答案值得很多 +1
    【解决方案2】:

    我只是让该字段可以为空(并且可能不可编辑,因为您不会在管理界面或通过表单更改它):

    class JobPosting(models.Model):
        ...
        ...
        search_vector = SearchVectorField(null=True, editable=False)
    

    迁移不会有任何问题。

    稍后您可以使该字段不可为空,但没有真正的理由这样做,因为无论如何您都会以编程方式对其进行更新。

    【讨论】:

      猜你喜欢
      • 2017-07-29
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 2018-05-25
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      相关资源
      最近更新 更多