2017-01-09 130 views
0

目前,這個代碼似乎要在每次循環迭代時發送到數據庫(Postgres)兩到四次。首先獲取(並創建)Type,然後獲取(並創建)Component。有沒有辦法在更少的數據庫旅程中做到這一點?如何避免在Django循環中多次訪問數據庫?

models.py

class Component(models.Model): 
    long = models.TextField() 
    type = models.SmallForeignKey('Type', models.CASCADE) 


class Type(models.Model): 
    type = models.TextField(unique=True) 


class Point(models.Model): 
    components = models.ArrayField(models.IntegerField(), default=[]) 

    def save_components(self, geocode): 
     _components = [] 
     for c in geocode: 
      ct = Type.objects.get_or_create(type=c['types'][0]) 
      _components.append(Component.objects.get_or_create(long=c['long_name'], type=ct).pk) 
     self.components = _components 
     self.save() 

傳入數據:

geocode = [ 
    { 
     "long_name" : "Luray", 
     "types" : [ "locality", "political" ] 
    }, 
    { 
     "long_name" : "Page County", 
     "types" : [ "administrative_area_level_2", "political" ] 
    }, 
    { 
     "long_name" : "Virginia", 
     "types" : [ "administrative_area_level_1", "political" ] 
    }, 
    { 
     "long_name" : "United States", 
     "types" : [ "country", "political" ] 
    } 
] 
+0

OK,'ct'和'組件'不是從哪裏冒出來的,它們都是從數據庫中提取出來的,你怎麼不能觸及數據庫並獲取信息呢? –

+0

@ShangWang我想應該可以在本地緩存,但這不是問題。目標是減少旅行次數,可能會減少到1或2次。我懷疑這是可能的,因爲在第一次旅行時所有的信息已經存在。 – dtgq

+1

爲什麼你要存儲一個主鍵數組,而不是使用ManyToManyField? –

回答

1

很多的時候,Django的做一個體面的工作緩存數據庫結果。如果你想有更多的控制,你可以做這樣的事情(前提是你沒有太多的類型)

 
class Point(models.Model): 
    components = models.ArrayField(models.IntegerField(), default=[]) 

    def save_components(self, geocode): 
     _components = [] 
     _types = {t.type: t for t in Type.objects.all()} 
     for c in geocode: 
      ct = _types.get(c['types'][0], None) 
      if not ct: 
       ct = Type.objects.create(type=c['types'][0]) 
      _components.append(Component.objects.get_or_create(long=c['long_name'], type=ct).pk) 
     self.components = _components 
     self.save() 

這應該救你查找現有類型所有的時間。您也可以嘗試推遲創建新類型和新組件(使用get()而不是get_or_create()並捕獲DoesNotExist異常)並稍後在函數中使用批量插入(這裏是doc link