2014-12-22 78 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()。