You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django数据库迁移失败:NOT NULL约束报错求助

Django数据库迁移失败排查与解决方案

问题描述

执行数据库迁移时持续报错:

django.db.utils.IntegrityError: NOT NULL constraint failed: new__orders_order.total

已尝试修改Cart模型相关字段的null/blank属性,以及在Order模型的save方法中捕获IntegrityError并重试生成code,但均未解决问题。

原因分析

从sqlmigrate输出的SQL语句来看,迁移逻辑是创建新表(如new__orders_order)并将旧表数据导入,新表的total字段已设置为允许NULL(real NULL)。报错说明导入数据时出现了矛盾:

  • 旧表orders_order的total字段原本是NOT NULL约束,但数据库中存在total为NULL的记录(可能通过手动修改数据库、跳过模型验证插入数据导致)
  • 迁移文件与模型定义不一致,生成的迁移逻辑未正确将total字段改为允许NULL

解决方案

步骤1:检查并修复旧表数据

  1. 进入数据库命令行(以SQLite为例):
    sqlite3 your_project_db.sqlite3
    
  2. 查看orders_order表的total字段约束:
    PRAGMA table_info(orders_order);
    
    观察total字段的notnull列值(1为NOT NULL,0为允许NULL)。
  3. 检查是否存在total为NULL的记录:
    SELECT COUNT(*) FROM orders_order WHERE total IS NULL;
    
  4. 如果存在NULL值,先修复数据(比如设置默认值0):
    UPDATE orders_order SET total = 0 WHERE total IS NULL;
    

步骤2:重新生成并执行迁移

  1. 备份当前数据库,避免数据丢失。
  2. 删除orders应用下编号为0014及之后的迁移文件(如果这些迁移是针对total字段修改的)。
  3. 重新生成迁移文件:
    python manage.py makemigrations orders
    
  4. 执行迁移:
    python manage.py migrate orders
    

步骤3:修复模型中的潜在问题

注意到Coupon模型的save方法缩进错误(定义在类外部),这会导致该方法无法生效,建议修复:

class Coupon(models.Model):
    code = models.CharField(max_length=20)
    start_date = models.DateField(default=timezone.now)
    end_date = models.DateField(null = True,blank = True)
    quantity = models.IntegerField()
    discount = models.FloatField()
    
    def save(self, *args, **kwargs):
        week = datetime.timedelta(days=7)
        self.end_date = self.start_date + week
        super(Coupon, self).save(*args, **kwargs)

内容的提问来源于stack exchange,提问作者Mo_Tech91

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:35:14