前言

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

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

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

问题2:migrate做了什么事情

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

实战案例

当我们了解清楚migrate的作用后,我们来看一个案例

首先我们创建一个项目orm_migrations_demo,接着创建2个app应用frontarticle,代码结构如下图



接着在front.models.pyarticle.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.pyINSTALL_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.db.utils.OperationalError: (1060, "Duplicate column name 'content'")

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

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



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

第一种报错情况总结

原因:执行migrate命令会报错的原因是。数据库的django_migrations表中的迁移版本记录和代码中的迁移脚本不一致导致的。

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

第二种报错情况

如果我们不管怎么执行migrate命令都会报错,那么就执行第二种方案

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

最新文章

  1. CI 扩展 Service
  2. 几种提高jQuery性能的代码
  3. Web Service 小练习
  4. JAVA学习随笔-.class
  5. js获取非行内样式
  6. ASP.NET在IE10,IE11中Form表单身份验证失效问题解决方法
  7. [Objective-c 基础 - 3.3] @property属性详解
  8. Form 重置记录编号(app_record.for_all_record)
  9. redis常见错误
  10. /etc/profile /etc/bashrc ~/.bash_profile ~/.bashrc ~/.bash_logout 说明及区别
  11. 国际知名CSS Reset 总结
  12. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock
  13. js如何判断数字是否有小数
  14. nginx 的安装、启动、停止与重启
  15. KeepAlived+Nginx 安装
  16. jQuery Ajax实例各种使用方法详解
  17. npm介绍和使用
  18. EOJ Monthly 2019.2 (based on February Selection) F.方差
  19. STL项目-学校演讲比赛
  20. linux 驱动cc1101

热门文章

  1. 前端知识-CS-01
  2. 有意思!强大的 SVG 滤镜
  3. 从本质彻底精通Git——4个模型1个周期1个史观1个工作流
  4. Android Studio之显示本地时间
  5. Web 前端 - 优雅地 Callback 转 Promise :aw
  6. Java学习之this关键字的使用
  7. go的令牌桶实现库 go-rate
  8. Dynamics CRM证书更换
  9. 关于ArrayList 中子方法 -- contains 疑惑解决
  10. QTableWidget导致程序崩溃