Django 模型迁移遇到的问题

本文概述了在Django项目中遇到的迁移问题,包括已存在的数据库表与未注册应用的配合、ORM模型与手动创建表的字段类型不匹配。提供了解决方案,如删除表重建、修改migration表及调整模型配置,确保迁移顺利进行。
摘要由CSDN通过智能技术生成

Django 模型迁移遇到的问题汇总

一、Django迁移前,数据库已经有迁移中建立的表了

问题描述:没有注册子应用contents,但是在客户端已经插入对应的数据表了。这时迁移会报错。

在这里插入图片描述
上图是所生成子应用的迁移文件。

解决方法:

方法1:迁移前删除子应用迁移文件对应的数据表 或者 删除数据库。

在这里插入图片描述
这里可以删除tb_content tb_content_category表,然后按照正常的程序去迁移这两个表的迁移文件。

方法2:不删除数据表,修改django_migrate表。在这里插入图片描述

查看django_migrate表,这个表记录了哪些文件已经迁移过了。
在这里插入图片描述
我们将对应的miagration文件填入django_migrate表,这样django就会认为自己迁移过了,从而后面修改模型迁移的工作可以正常进行。

二、orm模型 和 自己插入建的表字段类型不一致

执行迁移的过程中报错:

(venv) fan@ubuntu:Dmall$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, areas, auth, contents, contenttypes, goods, oauth, sessions, user
Running migrations:
  Applying goods.0002_goodsvisitcount...Traceback (most recent call last):
  File "/home/fan/PycharmProjects/Dmall/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "/home/fan/PycharmProjects/Dmall/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73,
   ...
django.db.utils.OperationalError: (3780, "Referencing column 'category_id' and referenced column 'id' in foreign key constraint 'tb_goods_visit_category_id_b3e36237_fk_tb_goods_category_id' are incompatible.")

意思是外键束tb_goods_visit_category_id_b3e36237_fk_tb_goods_category_id中引用列category_id和引用列id不兼容。

原因分析:

说明两个表关联的列数据类型不一致,比如:varchar 与 int,或者 int无符号 与 int有符号,都不行,必须要一模一样才可以。

我的报错是因为tb_goods_visit表中的category_id为bigint类型,tb_goods_category表中的id为int类型,它俩不一致。

问题分析:

1、查看迁移文件

显然,这里tb_goods_categoryint,而我们查看迁移文件goods\migrations\0001_initial.pyidbigint

        migrations.CreateModel(
            name='GoodsCategory',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
                ('update_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
                ('name', models.CharField(max_length=10, verbose_name='名称')),
                ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subs', to='goods.goodscategory', verbose_name='父类别')),
            ],
            options={
                'verbose_name': '商品类别',
                'verbose_name_plural': '商品类别',
                'db_table': 'tb_goods_category',
            },

查看 goods\migrations\0002_goodsvisitcount.py , 它依赖goods\migrations\0001_initial.py, 外键 也就按照上面的迁移文件goods\migrations\0001_initial.py中的 是 models.BigAutoField 即 bigint
在这里插入图片描述

2 查看导入数据库的数据sql文件:
...
DROP TABLE IF EXISTS `tb_goods_category`;
...
CREATE TABLE `tb_goods_category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `create_time` datetime(6) NOT NULL,
  `update_time` datetime(6) NOT NULL,
  `name` varchar(10) NOT NULL,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tb_goods_category_parent_id_5abc16fa_fk_tb_goods_category_id` (`parent_id`),
  CONSTRAINT `tb_goods_category_parent_id_5abc16fa_fk_tb_goods_category_id` FOREIGN KEY (`parent_id`) REFERENCES `tb_goods_category` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=556 DEFAULT CHARSET=utf8;
...

这里对django生成的表进行了删除重建操作,主键是int, 而 tb_goods_visit 外键依赖的 标记为bigint,所以出错了。

问题处理

下面开始修改主键字段,让它和数据库中主键的字段保持一致 (ps:我不想删表,所以主要操作都放在了操作迁移文件这块了)

1、将各应用下的在每个应用程序(app)的基础上设置字段类型,可以在apps.py中指定这一点。

goods\apps.py

from django.apps import AppConfig

class GoodsConfig(AppConfig):
    default_auto_field = 'django.db.models.AutoField' # Django3.2后这里默认是BigAutoField,这里我们改为AutoField
    name = 'goods'
2、 重新生成迁移文件,迁移

AutoField
在这里插入图片描述
迁移过程又出错了,还是上面的那个问题。但是又生成了一个文件goods\migrations\0003_alter_brand_id_alter_goodscategory_id_and_more.py,这个文件又依赖 goods\migrations\0002_goodsvisitcount.py

3 使用python manage.py showmigrations查看迁移情况

X的表示已经执行(迁移过的),没有的表示还没有迁移。显然,goods应用下的migration文件,只有第一步迁移了(goods\migrations\0001_initial.py)。
在这里插入图片描述
goods\migrations\0003_alter_brand_id_alter_goodscategory_id_and_more.pygoods\migrations\0002_goodsvisitcount.py删除,重新生成迁移,并执行迁移:

在这里插入图片描述
在此查看迁移情况,到这里问题得以解决。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值