2017-04-24 69 views
2

我的数据库中有一个ManyToMany字段,我想将其转换为ForeignKey关系。这种关系已经是一对多的关系,所以不会出现鸽派。将ManyToMany转换为ForeignKey(django)

我可以找到关于计算器最近的问题是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-loop。它的工作原理,但看起来将需要数天时间来处理数百万条记录:

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将运行快速简单的方法?我想通过查询有办法做到这一点。我只需要做一次。

在此先感谢您的帮助!

+0

如果你只需要做一次,那么我认为你的方法没问题,不能多说要花费的时间,也许你可以测试1000个对象,然后用它来计算整个数据库将花费多长时间 – kujosHeist

+0

基于1000个样本的试运行,这个天真的实现将花费60.55天来更新我的所有数据。 –

+0

好的工作在回答 – kujosHeist

回答

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] 
相关问题