一. python manage.py makemigrations
#在对应app下生成迁移文件
一般情况下,makemigrations 流程大概分成以下几个步骤:
- 创建 MigrationLoader 对象,加载 migration 文件,生成 MigrationGraph 对象(简单情况下是一组 migration 对象列表)
- 根据 models 定义,创建出 Project State
- 根据 MigrationGraph 对象创建出 Database State
- 创建 MigrationAutodetector 对象来比对 Database State 和 Project State 之间的差异
- 生成新的 Migration 对象
- 将 Migration 对象写入到新的 migration 脚本中
一句话总结:makemigrations时根据现有model信息 对比 本地migrations目录下的文件,根据差异创建新的migration文件;后一个文件会依赖前一个文件
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('artifact', '0002_platformmsgx'),
]
operations = [
migrations.CreateModel(
name='VersionSyn',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('region_id', models.CharField(max_length=50, verbose_name='区域ID')),
('product_ename', models.CharField(max_length=255, verbose_name='项目ID')),
('product_version', models.CharField(max_length=50, verbose_name='版本号')),
('syn_region', models.CharField(max_length=255, verbose_name='同步对象区域ID')),
('syn_ename', models.CharField(max_length=255, verbose_name='同步对象项目ID')),
('syn_version', models.CharField(max_length=50, verbose_name='同步对象版本号')),
('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
],
options={
'verbose_name': '版本同步记录',
'verbose_name_plural': '版本同步记录',
'db_table': 'version_syn',
},
),
]
由上可知:
migration文件中Migration类下存在属性
dependencies -- 本文件的依赖文件
operations -- 本文的操作内容
二. python manage.py migrate
#根据迁移文件执行迁移
migrate命令执行时Django会做4件事:
- 迁移判定,将你的项目中所有未迁移的变动文件进行迁移(Django会去查询django_migrations表判断你是否有新的迁移变动)再完成接下来的迁移后,便会在该表中生成一条迁移记录。
- 迁移映射关系django_contenttype表新增映射关系(app与模型关系)。
- 迁移权限auth_permission表新增权限。
- 执行迁移,生成数据表,或变动。
migrate --fake 只执行第一步,并生成迁移记录,忽略数据库中的表不生成表。
migrate --fake-initial 执行前三步,不实际变动数据库,如果有已存在的表不变动,其他继续生成
migrate 全部依次执行所有步骤。
涉及的数据库表格:
django_content_type # app -- model映射关系表
django_migrations # 迁移文件执行记录表
迁移经常会出现多种错误,需根据迁移流程和相关文件进行梳理
实际编程中多个人负责一个项目下不同模块,合成时容易出现migrate错误,避免?
个人避免这种错误的方法为:不是用django的migrate,而是手工创建数据库表,并编写对应的sql语句存储在工程文件中作为每次数据库初始化的sql脚本
参考: