【问题标题】:You are trying to add a non-nullable field stock without a default您正在尝试添加没有默认值的不可空字段库存
【发布时间】:2019-09-05 07:53:58
【问题描述】:

我在模型中添加了一个新字段,但之后我删除了 db.sqlite3(以确保我不会在下面出现错误)

agrawalo@:~/myapp> ls
README.md  config  core  manage.py  requirements.txt

但我在运行 makemigrations 时仍然收到此错误

agrawalo@:~/myapp> ./manage.py makemigrations
You are trying to add a non-nullable field 'high52' to stock 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


class Stock(models.Model):
    name = models.CharField(max_length=255)
    code = models.CharField(max_length=20, db_index=True)
    price = models.DecimalField(max_digits=19, decimal_places=2)
    diff = models.DecimalField(max_digits=19, decimal_places=2)
    open_price = models.DecimalField(max_digits=19, decimal_places=2)
    previous_close = models.DecimalField(max_digits=19, decimal_places=2)
    low52 = models.DecimalField(max_digits=19, decimal_places=2)
    high52 = models.DecimalField(max_digits=19, decimal_places=2)
    last_updated = models.DateTimeField()

    objects = DataFrameManager()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        self.last_updated = timezone.now()
        return super(Stock, self).save(*args, **kwargs)

    def __str__(self):
        return str(self.code)

low52 和 high52 是新添加的字段。请注意,其他现有字段都不会引发此错误。

【问题讨论】:

  • 您是否在模型中添加了任何新字段?
  • 我在模型中添加了一个新字段,但之后我删除了 db.sqlite3(以确保我不会在下面出现错误)
  • 不是删除数据库。这是关于迁移的。您需要为新添加的字段添加默认值或将该字段设为可选。根据您的用例做出决定。
  • 但是没有现有记录,那它为什么要抱怨。如何使字段可选?
  • 在您的问题本身中添加新添加字段的代码。

标签: django django-models


【解决方案1】:

您可以为该字段提供默认值

high52 = models.DecimalField(max_digits=19, decimal_places=2, default=0.0)

或者您可以将其设为可选

high52 = models.DecimalField(max_digits=19, decimal_places=2, null=True, blank=True)

您可以根据自己的选择做出决定。

要回答您有关该错误的问题,以前存在的字段可能已在初始迁移本身中创建,它们不需要默认值。但是对于新添加的字段,您需要为必填字段设置一个默认值,并且此默认值将填充到现有记录中。这不取决于您是否删除了现有数据库。这取决于该模型的当前迁移状态。由于这不是初始迁移,因此您需要提供默认值或将其设为可选。

【讨论】:

  • 有没有办法强制重新进行初始迁移?
  • 我的意思是有没有办法告诉 Django 这是应用程序的全新安装?
  • 如果您的应用程序仍处于早期开发阶段且尚未部署,您可以尝试删除已经迁移的文件并再次运行makemigrations。但这仅在开发的早期阶段是可取的。
  • 是的。应用程序的migrations 目录中以000 开头的文件。
  • 我删除了所有这些,但现在我得到“django.db.migrations.exceptions.NodeNotFoundError: Migration core.0010_log_action dependencies reference nonexistent parent node (u'core', u'0009_log_isactive')”它有效,我猜 pycache 也需要删除。
【解决方案2】:

是否删除数据库文件并不重要。 makemigrations 不检查数据库。

只有将不可为空的字段添加到新模型并进行初始迁移时,才能将其添加到模型。这是因为,在您进行初始迁移之后,Django 无法知道您是否在其他地方部署了您的应用程序,因此它无法知道那里是否有模型的实例。这会出错的情况:

  1. 在本地计算机上创建模型 X 并进行迁移。
  2. 将您的 Django 应用程序部署到服务器,其中的数据库填充有模型 X 的实例。
  3. 删除本地数据库,将不可为空的字段 Y 添加到模型 X,进行迁移。
  4. 将您的 Django 应用程序部署到服务器。
  5. 出现问题。

这里的解决方案是:

  • 将字段设置为 null=True
  • 为模型添加默认值。
  • 进行迁移时提供默认值。

在您的情况下,我会说提供一次性默认值是可以的,因为听起来您还没有填充数据库。

【讨论】:

  • 有没有办法强制重新进行初始迁移?我的意思是有没有办法告诉 Django 这是应用程序的全新安装?
  • 如果您完全确定某处没有数据库浮动,您可以删除该应用程序的迁移文件,然后再次运行 makemigrations。然后,Django 将为该应用程序生成一个新的初始迁移。
  • 一些警告(在您的情况下可能不适用):如果其他应用程序中的迁移依赖于您尝试删除的迁移,您的 makemigrations 命令将导致各种错误。因此,只有在您的结构和项目不太复杂的情况下才这样做,并且最好从所有应用程序中删除所有迁移,然后重新开始。作为一般规则:除非绝对需要并且确定没有生产数据库,否则永远不要删除迁移。
【解决方案3】:

您需要为high52 字段提供blanknull True。

high52 = models.SomeField(blank=True,null=True)

如果你不想这样,那么你可以选择这两个选项中的任何一个。

例如,如果 high52CharField,那么您可以选择 1 选项并提供一些值,例如 '..',或者您可以在您的 models.py 中设置默认值

【讨论】:

  • 但是为什么它只抱怨新添加的字段。我在模型中有其他字段也没有这些字段(空、空白、默认)。
猜你喜欢
  • 2016-01-04
  • 2020-06-03
  • 1970-01-01
  • 2020-07-12
  • 2021-08-25
  • 2017-10-09
  • 2016-05-09
  • 1970-01-01
  • 2021-09-06
相关资源
最近更新 更多