【问题标题】:How to migrate data from ManyToManyField to ForeignKey?如何将数据从 ManyToManyField 迁移到 ForeignKey?
【发布时间】:2014-05-20 15:48:57
【问题描述】:

我想将数据从 ManyToMany-Field 迁移到 ForeignKey-Field。由于我在之前的迁移中向另一个方向(从 ForeignKey 到 ManyToMany)迁移了数据,并且将一步部署这两个迁移,我想这应该可行。

我有这个模型:

class Log(models.Model):
    contacts = models.ManyToManyField(Contact, related_name='contact_logs', blank=True, null=True)

我添加了新字段:

class Log(models.Model):
    contact = models.ForeignKey(Contact, blank=True, null=True)
    contacts = models.ManyToManyField(Contact, related_name='contact_logs', blank=True, null=True)

然后我做了:

$ ./manage.py schemamigration myapp --auto
$ ./manage.py datamigration myapp move_contacts_data

现在我尝试编写数据迁移。这就是我以前的方式 将数据从 ForeignKey 迁移到 ManyToMany:

def forwards(self, orm):
   "Write your forwards methods here."
   for log in orm.Log.objects.all():
       if log.contacts:
           log.contact.add(log.contacts)
           log.save()

但这似乎并没有反过来奏效。我明白了:

$ ./manage.py migrate myapp                                   :(
Running migrations for myapp:
- Migrating forwards to 0072_move_contacts_data.
contacts:0072_move_contacts_data
Error in migration: myapp:0072_move_contacts_data
AttributeError: 'NoneType' object has no attribute 'add'

谁能帮帮我?

【问题讨论】:

    标签: django django-south data-migration


    【解决方案1】:

    如果您的 m2m 关系仅包含每个日志的单个联系人,您可以执行以下操作:

    def forwards(self, orm):
       "Write your forwards methods here."
       for log in orm.Log.objects.all():
           if log.contacts.all():
               assert log.contacts.count() == 1
               log.contact = log.contacts.get()
               log.save()
    

    如果关系包含多个联系人,您必须定义一种方法来确定要保存的联系人。这可以是任意日期字段或任何其他字段。无论哪种方式,您都会丢失一些数据。如何处理取决于您。

    【讨论】:

    • 非常感谢!一切正常。我刚刚迁移了大约 700 个数据集。
    【解决方案2】:

    你的想法是对的,你只是添加数据错误-contact-ForeignKey现在,所以你需要这样添加:

    def forwards(self, orm):
       "Write your forwards methods here."
       for log in orm.Log.objects.all():
           if log.contacts:
               log.contact = orm.Contact.objects.create(...some data from contacts...) 
               log.save()
    

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 2019-07-09
      • 2013-01-07
      • 2022-01-05
      • 2020-11-25
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      相关资源
      最近更新 更多