好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Django migrate报错的解决方案

前言

在讲解如何解决 migrate 报错原因前,我们先要了解 migrate 做了什么事情, migrate :将新生成的迁移脚本。映射到数据库中。创建新的表或者修改表的结构。

问题1:migrate怎么判断哪些迁移脚本需要执行?

它会将代码中的迁移脚本和数据库中 django_migrations 中的迁移脚本进行对比,如果发现数据库中,没有这个迁移脚本,那么就会执行这个迁移脚本。

问题2:编程客栈migrate做了什么事情

将相关的迁移脚本翻译成SQL语句,在数据库中执行这个SQL语句。 如果这个SQL语句执行没有问题,那么就会将这个迁移脚本的名字记录到 django_migrations 中。

实战案例

当我们了解清楚 migrate 的作用后,我们来看一个案例 首先我们创建一个项目 orm_migrations_demo ,接着创建2个app应用 front 和 article ,代码结构如下图

接着在 front.models.py 和 article.models.py 中创建模型

# front.models.py
class Article(models.Model):
    name = models.CharField(max_length=200)

# article.models.py
class FrontUser(models.Model):
    name = models.CharField(max_length=200)

接着在 settings.py 的 INSTALL_APPS 中将app注册

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'front',
    'article',
]

接着我们打开命令行,输入 makemigrations article ,再输入 makemigrations front ,此时2个app目录中都会出现迁移文件 0001_initial.py ,此时数据库中是没有表的,因为还没有执行迁移命令 接着我们执行 migrate article ,再输入 migrate front ,migrate发现数据库中没编程客栈有迁移脚本,那么就会执行刚才生成的2个迁移脚本,将迁移脚本翻译成SQL语句,然后创建了2张表,执行完成后,会将迁移脚本记录到 django_migrations 表中,数据库中表结构如下:

django_migrations 表中内容如下:

接下来我们在 article.models.py 中添加一个 content 字段

class Article(models.Model):
    name = models.CharField(max_length=200)
    content = models.CharField(max_length=200, null=True)

然后执行命令 makemigrations article ,会在项目中生成迁移文件 0002_article_content.py ,接着执行 migrate article ,执行迁移脚本,此时数据库中表 django_migrations 有3个迁移脚本

现在我们来模仿错误信息内容,我们将数据库中 django_migrations 表中的 0002_article_content 这行记录删除,然后我们来看下 0002_article_content 的代码

class Migration(migrations.Migration):

    dependencies = [
        ('article', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='article',
            name='content',
            field=models.CharField(max_length=200, null=True),
        ),
    ]

这个迁移脚本的作用是为article模型添加 content 字段,但是我们现在看一下 article 中的字段:

从上图中我们可以清楚的看到 article 表中已经有了 content 字段,那么我们再执行 migrate article 命令时,就会报错,说content字段重复了,报错信息如下

django.ZSlwKdb.utils.OperationalError: (1060, "Duplicate column name 'content'")

如果发生这种报错信息,解决办法是在 migrate 命名后添加参数 --fake , --fake 可以将指定的迁移脚本名字添加到数据库中。但是并不会把迁移脚本转换为SQL语句去修改数据库中的表

所以,我们可以执行命名 migrate article --fake ,会在 django_migrations 表中插入迁移脚本记录 0002_article_content ,如下图

此时数据www.cppcns.com库中表结构和django中的表结构完全一致,接下来执行迁移命令,就不会报错了

第一种报错情况总结

原因:执行 migrate 命令会报错的原因是。数据库的 django_migrations 表中的迁移版本记录和代码中的迁移脚本不一致导致的。 解决办法:使用 --fake 参数:首先对比数据库中的迁移脚本和代码中的迁移脚本。然后找到哪个不同,之后再使用 --fake ,将代码中的迁移脚本添加到 django_migrations 中,但是并不会执行sql语句。这样就可以避免每次执行 migrate 的时候,都执行一些重复的迁移脚本。

第二种报错情况

如果我们不管怎么执行 migrate 命令都会报错,那么就执行 http://www.cppcns.com 第二种方案

将出问题的app下的所有模型,都和数据库中的表保持一致。将出问题的app下的所有迁移脚本文件都删掉。再在 django_migrations 表中将出问题的app相关的迁移记录都删掉。使用 makemigrations ,重新将模型生成一个迁移脚本。使用 migrate --fake-initial 参数,将刚刚生成的迁移脚本,标记为已经完成(因为这些模型相对应的表,其实都已经在数据库中存在了,不需要重复执行了。)可以做其他的映射了。

到此这篇关于Django migrate报错的解决方案的文章就介绍到这了,更多相关Django migrate报错内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

查看更多关于Django migrate报错的解决方案的详细内容...

  阅读:36次