【问题标题】:Django migration from dynamic fieldsDjango 从动态字段迁移
【发布时间】:2017-10-30 10:42:02
【问题描述】:

我有以下 Django 模型:

class Apple(models.Model):
    text = models.TextField()

我已经有很多记录了,我想在模型中添加一个主题字段,所以它看起来像:

class Apple(models.Model):
    text = models.TextField()
    subject = models.CharField(max_length = 128)

。在这种情况下,我运行了一个 makemigrations,但由于主题可以为空,我需要在模型或迁移文件中设置一个默认值。

如果我想从文本中提取现有数据库行的主题(例如:text[:64]),正确的程序是什么?

我的解决方案是使用默认值创建迁移,运行管理命令来更新值,并使用新迁移删除主题的默认值。有更好的解决方案吗?它是什么?我可以在迁移本身中以某种方式组合/执行此操作吗?

Python:3.4.5 Django:1.9.2

【问题讨论】:

    标签: python django django-migrations


    【解决方案1】:

    您可以在迁移本身中执行此操作,在主题字段中创建带有blank=True, null=True 的迁移文件。

    class Apple(models.Model):
        text = models.TextField()
        subject = models.CharField(max_length=128, blank=True, null=True)
    

    然后再创建一个空的迁移文件。

    python manage.py makemigrations --empty yourappname
    

    将以下代码粘贴到该文件中。

    from django.db import migrations
    
    def set_subject(apps, schema_editor):
    
        Apple = apps.get_model('yourappname', 'Apple')
        for a in Apple.objects.all():
            a.subject = a.text
            a.save()
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('yourappname', 'name of above migration file'),
        ]
    
        operations = [
            migrations.RunPython(set_subject),
        ]
    

    【讨论】:

    • 如果 Apple 在数据库中有数百万个对象,这将花费太多时间。因此,应该对其进行迭代以减少内存使用量。 Apple.objects.all().iterator()
    【解决方案2】:

    对于包括 postgresql 在内的某些数据库,添加可为空的字段会更快,因此我会将您的方法更改为:

    1. 架构迁移使用null=True 创建字段(无需设置默认值)
    2. data migration 填充字段
    3. 架构迁移会从字段中删除 null=True

    您可以将这三个操作组合到一个迁移文件中。但是,用于数据迁移的 Django 文档建议您将它们分开。

    【讨论】:

      猜你喜欢
      • 2018-02-20
      • 2019-03-30
      • 2021-09-25
      • 2012-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-18
      • 2012-11-29
      相关资源
      最近更新 更多