Django:迁移到 NullBooleanField 失败,IntegrityError“包含空值”
Posted
技术标签:
【中文标题】Django:迁移到 NullBooleanField 失败,IntegrityError“包含空值”【英文标题】:Django: migration to NullBooleanField fails with IntegrityError "contains null values" 【发布时间】:2015-06-06 05:01:48 【问题描述】:我正在使用 Django 1.7 并尝试将名为 is_dispensing
的数据库字段从现有的 BooleanField
迁移到 NullBooleanField
。
我的迁移文件:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('frontend', '0007_practice_is_dispensing'),
]
operations = [
migrations.AlterField(
model_name='practice',
name='is_dispensing',
field=models.NullBooleanField(),
preserve_default=True,
),
]
运行 manage.py migrate
失败并出现此错误:
django.db.utils.IntegrityError: column "is_dispensing" contains null values
我的模型文件中的字段:
is_dispensing = models.NullBooleanField(blank=True)
以前是:
is_dispensing = models.BooleanField(null=True, blank=True)
当我添加它时,我被要求提供一个默认值,我将其设置为无。
我发现此消息令人困惑 - 我正在尝试将列类型迁移到 NullBooleanField
,那么为什么它不能包含空值?这就是这种列类型的全部意义,不是吗? :)
更新:另一件令人困惑的事情:如果我进入 Postgres 并查看应该包含该列的表,它实际上根本没有 is_dispensing
列。
【问题讨论】:
我认为这里发生的事情是第一次迁移(创建BooleanField(null=True, blank=True)
没有完全执行,因为 Django 1.7 不允许纯 BooleanField
字段具有空值。所以makemigrations
运行,但随后 migrate
失败。我……想?我仍然不明白当数据库中不存在该列时如何获得 IntegrityError
!
blank=True 仅影响生成(例如在管理员中)。它不会影响实际的数据库表。尝试 manage.py migrate --fake。这将在您的迁移表中添加一个条目。您将需要检查数据库表以查看它们是否实际上有 NOT NULL 并手动更新它们。不是一个完美的解决方案,但我需要查看迁移文件以通过 django 迁移来修复它。
【参考方案1】:
项目表中 slug 和您的应用的非唯一组合可能会导致此错误。我通过手动编辑确保我所有的项目 slug 都是唯一的,从而修复了它。
您可以添加blank = true外键定义,删除所有迁移并再次运行迁移...
【讨论】:
以上是关于Django:迁移到 NullBooleanField 失败,IntegrityError“包含空值”的主要内容,如果未能解决你的问题,请参考以下文章
将文件夹和文件结构从 django 1.3 迁移到 django 1.4 的最佳方法是啥?