通过 1.10 中的迁移播种数据
Seeding data through migration in 1.10
问题定义有点棘手,请耐心等待。
我有一个名为博客的模型。我有三个迁移。
0001_initial:为博客
创建table
0002_seed_data:将一些数据播种到此 table。要播种此数据,我使用:
all_blogs = Blog.objects.all()
for blog in all_blogs.iterator():
#some logic here
blog.save()
0003_add_column: 添加一个新列'title'到这个table
当我 运行 0003_add_column 在 0002_seed_data 已经 运行 在过去,它有效。
但是当我 运行 在空数据库上进行这些迁移时,它在 0002_seed_data 处失败,因为它无法在数据库中找到标题。它会给出类似于以下内容的错误:
django.db.utils.OperationalError: (1054, "Unknown column 'Blog.title' in 'field list'")
这对我来说就像先有鸡还是先有蛋的问题,因为 0002 无法 运行 直到 table 中不存在标题列。在 0003 中的 table 中有规定可以添加标题,但是不能 运行 直到 0002 有 运行。
一个简单的解决方案是更正顺序。这就是我过去一直在做的事情。但这意味着每次我向 table 添加一个新列时,它的顺序都必须更正。
快速搜索错误 returns 一些解决方案,其中大部分都谈到删除所有迁移并使用 makemigrations 重新进行迁移。这不能解决我的问题
那么有更好的方法吗?
您应该使用 SQL 命令来更改数据库中的任何内容。你可以使用 python 库,错误来了,因为你使用 Django class 模型,它有现在的标题字段,但是当它试图找到那个值时,那个时候没有值,所以最好从 SQL query 中获取值,执行您想对其执行的任何操作。
您没有显示您的迁移文件,但我猜您正在从您的模型文件中导入您的博客 class。如您所见,您不能这样做,因为它与迁移过程中此时的数据库状态不同步。
幸运的是,Django 迁移支持 "historical" 模型,可以根据数据库的状态正确表示模型。您无需导入模型,而是通过调用 apps.get_model()
在 RunPython 函数中以编程方式获取它。所以:
def my_function(apps, schema_editor):
Blog = apps.get_model('myapp', 'Blog')
all_blogs = Blog.objects.all()
...
请参阅 data migrations 上的文档。
问题定义有点棘手,请耐心等待。
我有一个名为博客的模型。我有三个迁移。
0001_initial:为博客
创建table0002_seed_data:将一些数据播种到此 table。要播种此数据,我使用:
all_blogs = Blog.objects.all()
for blog in all_blogs.iterator():
#some logic here
blog.save()
0003_add_column: 添加一个新列'title'到这个table
当我 运行 0003_add_column 在 0002_seed_data 已经 运行 在过去,它有效。
但是当我 运行 在空数据库上进行这些迁移时,它在 0002_seed_data 处失败,因为它无法在数据库中找到标题。它会给出类似于以下内容的错误:
django.db.utils.OperationalError: (1054, "Unknown column 'Blog.title' in 'field list'")
这对我来说就像先有鸡还是先有蛋的问题,因为 0002 无法 运行 直到 table 中不存在标题列。在 0003 中的 table 中有规定可以添加标题,但是不能 运行 直到 0002 有 运行。 一个简单的解决方案是更正顺序。这就是我过去一直在做的事情。但这意味着每次我向 table 添加一个新列时,它的顺序都必须更正。
快速搜索错误 returns 一些解决方案,其中大部分都谈到删除所有迁移并使用 makemigrations 重新进行迁移。这不能解决我的问题
那么有更好的方法吗?
您应该使用 SQL 命令来更改数据库中的任何内容。你可以使用 python 库,错误来了,因为你使用 Django class 模型,它有现在的标题字段,但是当它试图找到那个值时,那个时候没有值,所以最好从 SQL query 中获取值,执行您想对其执行的任何操作。
您没有显示您的迁移文件,但我猜您正在从您的模型文件中导入您的博客 class。如您所见,您不能这样做,因为它与迁移过程中此时的数据库状态不同步。
幸运的是,Django 迁移支持 "historical" 模型,可以根据数据库的状态正确表示模型。您无需导入模型,而是通过调用 apps.get_model()
在 RunPython 函数中以编程方式获取它。所以:
def my_function(apps, schema_editor):
Blog = apps.get_model('myapp', 'Blog')
all_blogs = Blog.objects.all()
...
请参阅 data migrations 上的文档。