Django 1.7.1需要字段的默认值-但数据库中没有条目。为什么?

问题描述 投票:2回答:3

我遇到了一个奇怪的问题。我在Mac OS X Yosemite上使用Django 1.7.1,并且已经配置了本地MySQL数据库。

通常,我创建一个模型,如果我想添加另一个字段,我只做一个./manage.py migrate,而Django创建一个新的数据库列。

我就是这么做的。这是我的模型:

from django.db import models
from django.utils.translation import ugettext as _


class Product(models.Model):
    CATEGORY_CHOICES = (
        ('apphosting', _('Application Hosting')),
        ('webhosting', _('Web Hosting'))
    )

    category = models.CharField(max_length=25, choices=CATEGORY_CHOICES)
    name = models.CharField(max_length=25)
    price_monthly = models.FloatField()

    def __unicode__(self):
        return self.name

请注意,我已经添加了字段price_monthly。然后,我做了一个./manage.py migrate

(mysphere)dmanser@ragamuffin:~/git/mysphere on master [!?]$ ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: crispy_forms
  Apply all migrations: customers, sessions, admin, sites, flatpages, contenttypes, products, auth
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  No migrations to apply.
  Your models have changes that are not yet reflected in a migration, and so won't be applied.
  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

好吧,我做了一个./manage.py makemigrations,结果是:

(mysphere)dmanser@ragamuffin:~/git/mysphere on master [!?]$ ./manage.py makemigrations
You are trying to add a non-nullable field 'price_monthly' to product 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)
 2) Quit, and let me add a default in models.py
Select an option:

奇怪的是,该模型还没有条目。那么,如果数据库中没有产品,为什么还要提供默认值?

我开始拔头发,昨天我尝试了几件事。 3小时后,我放弃了。

python django django-migrations
3个回答
6
投票

迁移系统经过设计,因此一次迁移可以应用于多个数据库。例如,您可能具有开发版本,登台版本以及一个或多个生产版本。这就是为什么make迁移与applying迁移是截然不同的步骤,也是为什么makemgirations不能仅查看当前活动的数据库以查看其没有任何行的原因。如果您随后尝试将迁移应用于具有该功能的数据库怎么办?

您所遇到的解决方案很简单:由于没有行,因此选项1(在所有现有行上设置默认值)根本不会做任何事情。因此,选择选项1,以及您喜欢的任何值。


1
投票

您之前已经应用了迁移,所以表已经创建。现在,您将添加一列,该列不能为null,但尚未定义默认值。

由于迁移将在现有表中添加一列,因此它需要足够的数据,因此您的迁移不会违反架构;因此提示。

如果要删除表,然后运行迁移,则不会遇到此错误。但是,由于初始迁移已经创建了该表,因此任何将来的迁移都不会违反其参照完整性。


0
投票

我遇到过很多次,假设您的项目myproject中有一个名为app1的应用程序,在这种情况下,您可以做的最好的事情是删除并删除app1 / migrations,然后重试它应该可以正常工作

© www.soinside.com 2019 - 2024. All rights reserved.