django migrate 失效/报错

django的表同步机制是,在app目录下生成一个migrations文件,里面按数字0001 0002 0003….开头的文件来记录每次的数据库变化(执行 makemigrations)。

当最新的一条上述文件被执行时(执行migrate),django会对比数据库的表django_migrations中记录和最新的000N文件内容,执行成功后会在此表中生成记录。

当migrate命令失效时,多半是因为数据库表django_migrations内容和migrations中文件内容不一致导致的。

对于类似的情况有如下处理方式:

1、如果数据库字段一切正常与migrations文件中记录一致,只是在执行migrate文件时会报错。

python manage.py migrate --fake

执行此命令的结果是,首先并不执行000N文件的数据结构的变化,但将django_migrations中最新的记录同步为migrations中的最新文件,然后再后续的变化将正常运行。

2、对于数据库字段与migrations文件中记录不一致的情况

python manage.py dbshell #进到数据库中

select * from django_migrations where app='appname'; #查看同步的文件记录

delete from django_migrations where app='appname'; #删掉历史记录

退出数据库

rm -rf appname/migrations/   #删掉历史的同步文件
python manage.py makemigrations appname  #重新开始同步数据库
python manage.py migrate

方案一

python manage.py dbshell 进到数据库中
手工修改数据库的表列,直到和修改文件完全一致。

python manage.py migrate --fake APP_NAME #注意此处必须加APP_NAME,以免将其它待执行的格式文件都fake执行了。忽略执行,但将表置为最新的一条django_migrations,之后就可以继续正常索引表的变化。

方案二

删掉migrations/中和数据库不一致的新文件

python manage.py dbshell #进到数据库中

select * from django_migrations where app='appname'; #查看同步的文件记录
删掉最新执行的记录,直到和migrations/中已成功执行的文件相匹配。
delete from django_migrations where id=ID;
Migrations for 'test':
  test/migrations/0033_auto_20210813_0625.py
    - Create model PermissionTemplate
    - Remove field is_admin from siteuser
    - Add field ali to testsetting  #执行到此处报错了,如ali是FK,且是别的APP中的models
    - Create model StaffUser

这种情况是因为,执行的第三条增加的字段是FK字段,且ali这个对应的models是其它APP中的,还没有创建。导致文件只执行了一半。

此时即使创建了外表的ali这个models,也无法顺利执行migrate。会报错误PermissionTemplate表已经存在。

此时在django_migrations这个大表中0033_auto_20210813_0625并没有被加入记录。

处理办法:

1.先找到makemigrations执行时列出的要执行变化,如上面代码所示。

2.进入数据库,按从上往下顺序对比数据库的表实际结构,以确定到底数据库到底同步到了哪里。如下

desc test_siteuser; #查看此表的结构,是否已经删掉了is_admin字段。

3.打开0033_auto_20210813_0625.py文件,将已经执行的代码注释掉。注意,注释前先备份文件。

cp 0033_auto_20210813_0625.py  0033_auto_20210813_0625.py.bak
Generated by Django 3.2.4 on 2021-08-13 06:25

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('app1', '0011_**'),
        ('app2', '__first__'),
        ('test', '0032_***'),
    ]

    operations = [
        # migrations.CreateModel(
        #     name='PermissionTemplate',
        #     fields=[
        #         ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
        #         ('name', models.CharField(blank=True, max_length=100, null=True, verbose_name='名称')),
        #         ('permissions', models.TextField(blank=True, null=True, verbose_name='权限|分割')),
        #         ('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')),
        #     ],
        # ),
        # migrations.RemoveField(
        #     model_name='siteuser',
        #     name='is_admin',
        # ),

        migrations.AddField(
            model_name='joysetting',
            name='ali',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='', to='', verbose_name='账号'),
        ),

        migrations.CreateModel(
            name='StaffUser',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
               # ('PermissionTemplate', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='joying.permissiontemplate', verbose_name='管理员权限模板')),
            ],
        ),
    ]

注意,要注释干净。如上述代码的最后一行命令,是已经被注释掉的表,在这里也要注释掉。注意因为此时是FK,会出现下面的6小节的问题。

4.执行此变化。

python3 manage.py migrate

5.将0033_auto_20210813_0625.py文件的注释全部去掉,回复原状。

6.如果以下这种情况

ValueError: Related model 'test.permissiontemplate' cannot be resolved

那么可以采取两种方式:

a.方式一

删掉数据库中permissiontemplate,然后将0033_auto_20210813_0625.py中原来注释的创建permissiontemplate部分打开。重新执行python3 manage.py migrate。

b.方式二

将0033_auto_20210813_0625.py中原来注释的创建permissiontemplate部分复制到前一个文件如0032_***.py中。再执行python3 manage.py migrate。

注意,无论采取何种方式执行成功后,最好恢复0032_***.py和0033_auto_20210813_0625.py等原文件。

Original: https://blog.csdn.net/u010145988/article/details/116997191
Author: 寒木
Title: django migrate 失效/报错

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/736652/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球