在具有PostgreSQL的Django 1.11中,我有两个具有一对一关系的模型。这两个模型在models.py
中的定义如下:
class Book(models.Model):
info = JSONField(default={})
class Author(models.Model):
book = models.OneToOneField(Book, on_delete=models.CASCADE)
关于这些模型的自动创建的迁移文件如下:
class Migration(migrations.Migration):
dependencies = [
('manager', '0018_some_migration_dependency'),
]
operations = [
migrations.CreateModel(
name='Book',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('info', JSONField(default={})),
],
),
migrations.AddField(
model_name='author',
name='book',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='manager.Book'),
),
]
这些实现已成功运行。除了这种迁移,我们还进行了其他一些与项目其他任务相关的迁移。
由于我们今天进行了设计更改,因此我们决定将所有Book信息数据移至我们的云存储中。为此,我实现了一个自定义迁移代码,如下所示:
def push_info_to_cloud(apps, schema_editor):
Author = apps.get_model('manager', 'Author')
for author in Author.objects.all():
if author.book.info is not None and author.book.info != "":
# push author.book.info to cloud storage
author.book.info = {}
author.book.save()
def pull_info_from_cloud(apps, schema_editor):
Author = apps.get_model('manager', 'Author')
Book = apps.get_model('manager', 'Book')
for author in Author.objects.all():
# pull author.book.info back from cloud storage
book = Book.objects.create(info=info)
author.book = book
author.save()
class Migration(migrations.Migration):
dependencies = [
('manager', '0024_some_migration_dependency'),
]
operations = [
migrations.RunPython(push_info_to_cloud, pull_info_from_cloud)
]
正如代码说明的那样,此迁移将每个非空的图书信息数据推送到我们的云存储中,并用数据库中的空dict替换它。我已经来回测试了此迁移,并确保正向和反向迁移都能成功进行。
然后,为摆脱多余的Book
表和book
表中的Author
列,我删除了Book
模型和OneToOneField
书本字段Author
模型中运行并运行manage.py makemigrations
,这将导致以下自动生成的迁移代码:
class Migration(migrations.Migration):
dependencies = [
('manager', '0025_some_migration_dependency'),
]
operations = [
migrations.RemoveField(
model_name='user',
name='book',
),
migrations.DeleteModel(
name='Book',
),
]
运行manage.py migrate
确实有效。最后,删除Book
表和book
表的Author
列。
现在,问题是;当我想迁移回0024_some_migration_dependency
时,在执行最新的迁移文件时出现以下错误:
Unapplying manager.0026_auto_20190503_1702...Traceback (most recent call last):
File "/home/cagrias/Workspace/Project/backend/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
psycopg2.IntegrityError: column "book_id" contains null values
我看到了这个https://github.com/webdevelopers-eu/jquery-dna-template/。为此,我这次通过使用Book
参数来手动重新创建book
模型和Author
模型的OneToOneField blank=True, null=True
字段。但是,在我成功地应用了上面的迁移之后,向后迁移时也会遇到相同的例外情况。
可能是什么问题?
答案 0 :(得分:0)
我设法通过更改迁移顺序来解决问题。
正如我在问题中提到的,我通过在blank=True, null=True
和info
字段中添加book
参数来应用this answer。但是它的相关迁移文件是在将我们的图书信息移动到云存储的迁移文件之后创建的。当我更改了这两个迁移文件的顺序后,问题就解决了。