django queryset去除重复,django queryset json
对象关系映射(ORM)使得与SQL数据库的交互更加容易,但是它也被认为是低效的,并且比原始的SQL更慢。
有效地使用ORM意味着你需要了解它是如何查询数据库的。本文将关注如何有效地使用Django ORM系统来访问中型到大型数据集。
Django的查询集是惰性的。Django的queryset对应于数据库中的几个记录(行),并通过可选查询进行过滤。例如,以下代码将获取数据库中所有名为“Dave”的人:
person _ set=person . objects . filter(first _ name= Dave )上述代码不运行任何数据库查询。可以使用person_set,给它添加一些过滤条件,或者把它传递给一个函数。这些操作都不会发送到数据库。这是正确的,因为数据库查询是显著影响web应用程序性能的因素之一。
要真正从数据库中获取数据,您需要遍历查询集:
对于人员集中的人员:
打印(个人姓氏)
Django的queryset有缓存。当您遍历queryset时,将从数据库中检索所有匹配的记录,然后转换成Django的模型。这叫执行(eval(232,232,232);颜色:rgb(38,38,38);边距:0px填充:0px背景:rgb(249,249,249);pet _ set=pet . objects . filter(species= Dog )
#执行并缓存查询。
对于宠物集中的宠物:
打印(宠物名)
#缓存用于后续迭代。
对于宠物集中的宠物:
打印(宠物姓氏)
If语句将触发queryset的执行。queryset的缓存最有用的地方是可以有效的测试queryset是否包含数据,只有在有数据的情况下才会遍历:
restaurant _ set=restaurant . objects . filter(cuisine= Indian )
# `if语句将触发queryset的执行。
如果餐厅设置:
#遍历时使用缓存中的数据。
对于餐厅集合中的餐厅:
打印(餐馆名称)
如果你不需要所有的数据,queryset的缓存可能是个问题。有时候,你可能只是想知道有没有数据,而不是遍历所有的数据。在这种情况下,简单地用if语句判断,会完全执行整个queryset,把数据放入缓存,虽然你并不需要这些数据!
city _ set=city . objects . filter(name= Cambridge )
# `if语句将执行queryset.
如果城市设置:
#我们不需要所有的数据,但是ORM还是会得到所有的记录!
print(至少有一个叫剑桥的城市还在!)要避免这种情况,可以使用exists()方法检查是否有数据:
tree _ set=tree . objects . filter(type= decoditive )
对# `exists()的检查可以防止数据被放入queryset的缓存中。
如果tree_set.exists():
#不从数据库中获取数据,从而节省带宽和内存
print(世上还有硬木树!)
当queryset非常大时,缓存就会成为问题。在处理成千上万条记录时,一次性将其加载到内存中是一种浪费。更糟糕的是,巨大的queryset可能会锁定系统进程,将你的程序带到崩溃的边缘。
为了避免在遍历数据时进行queryset缓存,可以使用iterator()方法获取数据,并在处理完数据后将其丢弃。
star_set=Star.objects.all()
# `iterator()`一次只能从数据库中获取少量数据,这样可以节省内存。
对于star_set.iterator()中的star:
Print(star.name)当然,使用iterator()方法防止缓存生成,意味着在遍历同一个queryset时,查询会被重复执行。因此,在使用iterator()时要小心,并确保您的代码在操作大型queryset时不会重复执行查询。
如果查询集很大,那么If语句就是一个问题。如前所述,查询集缓存对于组合if语句和for语句非常强大,它允许在查询集上进行条件循环。但是,对于大型查询集,不适合使用查询集缓存。
最简单的解决方案是将exists()和iterator()结合起来,通过使用两个数据库查询来避免使用查询集缓存。
molecule _ set=molecule . objects . all()
#一个数据库查询,用于测试是否存在任何行。
if molecule_set.exists():
#另一个数据库查询开始批量提取行。
对于molecule_set.iterator()中的分子:
print(molecule.velocity)更复杂的方案是,在开始循环之前,使用Python的“高级迭代法”查看iterator()的第一个元素,然后决定是否循环。
atom_set=Atom.objects.all()
#一个数据库查询开始批量提取行。
atom _ iterator=atom _ set . iterator()
#查看迭代器中的第一项。
尝试:
first_atom=next(atom_iterator)
除了StopIteration:
#找不到任何行,所以什么也不做。
及格
否则:
#至少找到一行,所以迭代
#所有行,包括第一行。
从itertools导入链
对于链中的原子([第一个原子],原子集):
打印(原子质量)
防止不当优化queryset的缓存用于减少程序对数据库的查询。在正常使用情况下,它将确保仅在需要时才查询数据库。
使用exists()和iterator()方法优化程序的内存使用。但是,由于它们不生成queryset缓存,因此可能会导致额外的数据库查询。
所以编码的时候需要注意。如果程序开始变慢,你需要看看代码的瓶颈在哪里,是否会有一些小的优化可以帮到你。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。