2014-12-22 93 views
1

是否有這些查詢之間的區別:Django。與延遲get_or_create優化

category, _ = models.Category.objects.get_or_create(
    title=some_title, 
    brick=node_id, 
    parent=parent, 
) 

和:

category, _ = models.Category.objects.defer('data').get_or_create(
    title=some_title, 
    brick=node_id, 
    parent=parent, 
) 


凡的分類模型是這樣的:

class Category(Model): 
    title = models.CharField(max_length=255, blank=True, null=True) 
    brick = models.IntegerField(
     primary_key=True, 
    ) 
    parent = models.ForeignKey('self', blank=True, null=True) 
    data = models.TextField(blank=True, null=True) # very large text 

回答

1

這個作品大多爲你所期望的。

從數據庫中檢索對象時,延遲不會選擇字段,但請注意,即使該字段被延遲,它在get查詢的WHERE子句中也可用,以檢查是否必須創建對象正如人們所期望的那樣)。如果對象不可用,則會發出第二個INSERT,插入在get_or_create方法中指定的所有字段,即使是最終在defer調用中指定的字段。

唯一的滋擾是創建一個對象,還不存在的時候,你不get_or_create指定一個字段,你defer,在你的情況,然後再嘗試訪問創建的對象上這一特定領域,生成額外的(第三個)查詢來從db中獲取該字段(即使我們知道該字段不存在)。

# Model has fields a and b, b being optional 
a, c = Model.objects.defer('b').get_or_create(a=1) # Two queries, one to get, the second to insert (ignore that sqlite does 3 queries here) 
# c is True 
# a is now a deferred object 
a.a # doesn't hit the db again 
a.b # hits the db trying to retrieve the b field 

相反,如果你插入的對象,而無需指定的延遲也不是可選字段,你不打數據庫中的第三次試圖獲取創建對象上的可選字段。

# Model has fields a and b, b being optional 
a, c = Model.objects.get_or_create(a=1) # Two queries as before 
# c is True 
# a is NOT a deferred object 
a.a # doesn't hit the db 
a.b # no db hit, b being empty 

不同的情況下會是一個在這裏裝載的對象與遞延領域,試圖挽救這個目的,本documentation指出:

當調用save()的情況下,與延期字段,只有加載的字段將被保存。有關更多詳細信息,請參閱save()。