将ManyToMany转换为ForeignKey(django)

时间:2017-04-24 21:20:20

标签: python django postgresql

我的数据库中有一个ManyToMany字段,我希望将其转换为ForeignKey关系。这种关系已经是一对多关系,所以不会有任何关系。

我在stackoverflow上找到的最接近的问题是this more complicated situation in a different framework/language

我的简化django模型如下所示。有问题的字段已经存在于数据库中,我们只需要填充DbLocation.pattern字段。

class DbPattern(models.Model):
    locations = models.ManyToMany(DbLocation) #trying to remove this
    ...

class DbLocation(models.Model)
    pattern = models.ForeignKey(DbPattern) #and replace it with this
    ...

我天真的解决方案是嵌套的for循环。它有效,但看起来处理数百万条记录需要数天时间:

patterns = DbPattern.objects.all()
for p in patterns:
    locs = p.locations # there ary many locations
    for l in locs:
        l.pattern = p # each location has exactly 1 pattern.

有没有一种简单的方法可以在Python / Django或PostreSQL中快速实现这一点?我想有办法通过查询来做到这一点。我只需要做一次。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

通过一些简单的调整,我设法获得了几个数量级的加速。可能会实现更快的加速,但这足以达到我的目的。

天真代码(1000个样本需要793秒)

patterns = DbPattern.objects.all()
for p in patterns:
    locs = p.locations # there ary many locations
    for l in locs:
        l.pattern = p # each location has exactly 1 pattern.
        l.save()

第一次改进(1000份样本需要11秒)

patterns = DbPattern.objects.all()
for p in patterns:
    locs = p.locations
    locs.update(pattern=p)

第二次改进(1000份样本需要2.5秒)

patterns = DbPattern.objects.all()
[p.locations.all().update(pattern=pattern) for p in patterns]