Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django模型函数性能_Python_Django - Fatal编程技术网

Python Django模型函数性能

Python Django模型函数性能,python,django,Python,Django,我不知道如何命名这个问题,如果可以,请提出更好的建议 我有两个模型。第一个模型存储了树(tree)的信息。第二个是一个模型,用于在重新种植树木时存储信息(TreeResolution)。树中名为“planted_date_real()”的函数通过查看TreeResolution中的最新记录来计算上次种植树的时间 trees = Tree.objects.all() for tree in trees: date = tree.planted_date_real() 我对此有性能问题。假设

我不知道如何命名这个问题,如果可以,请提出更好的建议

我有两个模型。第一个模型存储了树(tree)的信息。第二个是一个模型,用于在重新种植树木时存储信息(TreeResolution)。树中名为“planted_date_real()”的函数通过查看TreeResolution中的最新记录来计算上次种植树的时间

trees = Tree.objects.all()
for tree in trees:
   date = tree.planted_date_real()
我对此有性能问题。假设数据库中有10000棵树。如果我打电话给那10000棵树,想知道最后一次种植的日期,Django会打10000次电话给TreeResolution表

我知道“与select_相关的例程”,但是,只有在正在处理的表中使用外键时,该例程才起作用

任何帮助都将不胜感激

**请注意,我知道planted_date_real()函数有问题,它用于说明目的。我想弄清楚的是,在对objects.filter()results中的所有对象进行函数调用(过滤不同的表)时,如何在模型中使用函数,这些函数可以“批量加载”数据,而不会对数据库进行无数次调用

树模型

class Tree(models.Model):
    name = models.CharField(max_length=200,blank=True)
    planted_date = models.DateTimeField(default = timezone.now,blank=True)

    def planted_date_real(self):
        #Calling data from TreeResettlement table is causing performance issues.  
        #Is there some way of loading this table to memory when the function is called again?
        resettlements = TreeResettlement.objects.filter(tree=self)

        if len(resettlements) > 0:
            return(resettlements[len(resettlements)-1].date)
        else:
            return(self.planted_date)
class TreeResettlement(models.Model): 
    tree = models.ForeignKey(Tree,on_delete=models.CASCADE)   
    date = models.DateTimeField(default = timezone.now,blank=True) 
    keep_main_stem = models.BooleanField() 
树状沉降模型

class Tree(models.Model):
    name = models.CharField(max_length=200,blank=True)
    planted_date = models.DateTimeField(default = timezone.now,blank=True)

    def planted_date_real(self):
        #Calling data from TreeResettlement table is causing performance issues.  
        #Is there some way of loading this table to memory when the function is called again?
        resettlements = TreeResettlement.objects.filter(tree=self)

        if len(resettlements) > 0:
            return(resettlements[len(resettlements)-1].date)
        else:
            return(self.planted_date)
class TreeResettlement(models.Model): 
    tree = models.ForeignKey(Tree,on_delete=models.CASCADE)   
    date = models.DateTimeField(default = timezone.now,blank=True) 
    keep_main_stem = models.BooleanField() 
树中名为
planted\u date\u real()
的函数计算最后一次种植树的时间

在这里,您对数据库系统进行了一些假设,这些假设通常不成立。例如,如果检索记录,顺序可以是任何顺序,而不是按时间顺序

您可以使用聚合来获得最大值,如:

from django.db.models import Max

class Tree(models.Model):
    name = models.CharField(max_length=200,blank=True)
    planted_date = models.DateTimeField(default = timezone.now,blank=True)

    def planted_date_real(self):
        last = self.treeresettlement_set.aggregate(last=Max('planted_date'))['last']
        return last or self.planted_date
从django.db.models导入最大值
类树(models.Model):
name=models.CharField(最大长度=200,空白=True)
日期=models.DateTimeField(默认值=timezone.now,blank=True)
def植入日期真实(自我):
last=self.treereresolution\u set.aggregate(last=Max('planted\u date'))['last']
返回上一个或自己的日期
但是,如果您想批量注释所有树,这仍然不是很有效,因为这会导致每个树都有一个额外的查询。然后我们可以对其进行如下注释:

trees = Tree.objects.annotate(
    last_planted=Coalesce(Max('treeresettlement__planted_date'), 'planted_date')
)
trees=Tree.objects.annotate(
最后一次种植=合并(最大(“种植日期”),“种植日期”)
)
因此(这个查询集的)每棵树都会有一个属性
last\u planted
,这些属性都会在同一个查询中解析。

只需在您的查询集中使用last()函数,同时排序以获取最后一条记录并返回其日期

def planted_date_real(self):  
    resettlement = TreeResettlement.objects.filter(tree=self).order_by("date").first()
    return resettlement.date

编辑: 如果你想要最后一棵树,只需要从树上获取它

last_tree = TreeResettlement.objects.all().order_by("date").first().tree

那么您想要每棵树的最大重新安置日期吗?类似于这样的是-TreeResolution表和tree modelAnnotate中的planted_date字段之间的最大值看起来很有希望。我希望能有一些方法在模型中保留函数中的所有逻辑。你看到的函数是很多函数中的一个,我只是用最简单的一个来说明purposes@ceds当前位置它仍然在模型中。如果您只需要对有限数量的树进行计算,那么它就可以正常工作。但是如果你需要大量的数据,最好是进行注释。那么在模型中没有“批量”函数(植入日期和真实(自我))的方法吗?这需要在外面发生吗?我认为Django有一种奇特的方法可以将表加载到内存中,而不必执行10000 db的操作calls@ceds:例如,您可以重写对象管理器来封装这些调用,这可能是隐藏所有注释的最佳方式。但据我所知,没有;没有优雅的方式来指定注释。谢谢,我会给你更多的时间,也许其他人有一个花哨的窍门。如果没有什么,我就同意你的回答