【发布时间】:2019-09-22 05:52:43
【问题描述】:
我在 Django 1.11 和 PostgreSQL 中有两个具有一对一关系的模型。这两个模型在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'),
),
]
这些实施已成功运行。除了这次迁移之外,我们还有一些与我们项目的其他任务相关的其他额外迁移。
由于我们今天所做的设计更改,我们决定将所有图书信息数据移动到我们的云存储中。为此,我实现了一个自定义迁移代码,如下所示:
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)
]
正如代码告诉自己的那样,此迁移将每个非空书籍信息数据推送到我们的云存储,并用数据库中的空字典替换它。我已经来回测试了这种迁移,并确保向前和向后迁移都成功。
然后,为了摆脱Author 表中多余的Book 表和book 列,我删除了Author 模型中的Book 模型和OneToOneField book 字段并运行@987654332 @,这导致以下自动生成的迁移代码:
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表和Author表的book列。
现在,问题是;当我想迁移回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
我见过这个answer。为此,我手动重新创建了Book 模型和Author 模型的OneToOneField book 字段,这次使用blank=True, null=True 参数。但是在我成功应用上述迁移后,我在向后迁移时遇到了同样的异常。
可能是什么问题?
【问题讨论】:
标签: python django postgresql psycopg2 django-migrations