📜  Django数据库迁移(1)

📅  最后修改于: 2023-12-03 15:00:27.805000             🧑  作者: Mango

Django 数据库迁移

在 Django 中,一个模型类对应着一个数据库表,Django 提供了迁移(migration)机制,可以方便地对数据库表进行操作,包括创建、修改和删除等操作,而不必手动编写 SQL 语句。

基本操作
1. 创建迁移文件

通过以下命令可以创建一个空的迁移文件:

python manage.py makemigrations

这个命令会在app/migrations/目录下生成一个新的迁移文件,其中包含了相应的操作指令,但是并没有进行操作。

2. 模型的修改操作

例如,我们要在某个模型类中添加一个新的字段:

from django.db import models

class Course(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()

添加一个新的学分字段:

from django.db import models

class Course(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    credits = models.IntegerField(default=0)
3. 执行迁移操作

通过以下命令可以执行数据库的迁移操作:

python manage.py migrate

这个命令会将之前创建的迁移文件,即对模型的修改指令,实际应用到数据库中,从而修改数据库结构。

数据库迁移高级操作
1. 回退迁移

如果我们发现新的迁移(可以通过python manage.py showmigrations查看)有问题,需要回退到上一个迁移。可以通过以下命令回退迁移:

python manage.py migrate appname N-1

其中appname为应用名称,N-1表示回退到上一个迁移。

2. 模型数据转换

如果我们需要将一个已有的模型转换成一个新的模型,可以通过下面的操作:

添加新字段

from django.db import models

class Course(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    credits = models.IntegerField(default=0)

class Grade(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    student = models.CharField(max_length=100)
    score = models.FloatField()

移除已有字段

from django.db import models

class Course(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()

class Grade(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    student = models.CharField(max_length=100)
    score = models.FloatField()

修改字段

from django.db import models

class Course(models.Model):
    course_name = models.CharField(max_length=100)
    description = models.TextField()

class Grade(models.Model):
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    student = models.CharField(max_length=100)
    score = models.FloatField()
3. 运用RunPython修改数据

如果 Django 没有自动执行我们的自定义数据迁移操作,可以将这些操作放在RunPython操作中。

例如,对于一个已有的模型,我们要通过对一个字段的数据进行处理,使其变为一个新的字段。

from django.db import migrations, models

class Migration(migrations.Migration):

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

    operations = [
        migrations.AddField(
            model_name='show',
            name='new_field',
            field=models.IntegerField(null=True),
        ),
        migrations.RunPython(populate_new_field),
    ]

def populate_new_field(apps, schema_editor):
    Grade = apps.get_model('appname', 'Grade')
    for grade in Grade.objects.all():
        grade.new_field = grade.old_field * 100
        grade.save()

在这里,我们通过RunPython操作来修改数据。它接受一个函数作为参数,该函数接受两个参数:appsschema_editor

apps参数提供了与应用关联的模型,可以使用get_model()获得该模型的类。schema_editor提供了对正在运行的数据库的访问权限。

4. 多个应用之间的关联

如果我们有多个应用,其中一个应用的模型需要引用另一个应用的模型,可以通过外键关联实现。

例如,我们有两个应用blogcomments,其中博客需要引用评论功能,需要在blog/models.py中添加外键字段:

from django.db import models
from comments.models import Comment

class BlogPost(models.Model):
    title = models.CharField(max_length=150)
    content = models.TextField()
    comments = models.ForeignKey(Comment, on_delete=models.CASCADE)
结语

Django 的迁移机制极大地方便了数据库的操作,有了它,我们可以在开发过程中灵活地调整数据模型。同时,它也提供了丰富的高级操作,可以满足我们在开发过程中遇到的各种需求。