导读:今天首席CTO笔记来给各位分享关于djangoorm如何优化的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
python脚本中使用django orm
项目开发中,经常会遇到一个需求:将数据从旧数据库中导入到新数据库中。比如从SQL Server中导入到新的My SQL数据库中。一般可以借助pymysql和pymssql写脚本完成导入。但是字段特别多的时候,如果能借助Django 的orm, 则会方便很多。
在manage.py目录创建py文件 import_data.py
app.models
settings.py中配置多个数据库
如何在django系统外使用django的ORM
sqlalchemy使用上有两个层次,1是使用sql expression, 说白可以让你用python写sql, 2是它的orm, orm是使用session的,自行管理session生存期,自行在多个过程中传递session,自行管理事务。写法上是通常的transaction script(java常说的贫血的domain model)模式。实际编码通常1和2混合编程。
django通过中间件部分隐藏了连接/事务管理的概念,写法上也比较简单,接近java常说的充血的domain model. 内容上也没有sqlalchemy 的sql expression层次。 易用性就体现出来了。
不过用过的orm中,能达到sqlalchemy这样高度的orm, 还没有在其他语言中看到。 ruby有sequal, java的jooq都有部分sqlalchemy思想的影子。
如何优化 Django REST Framework 的性能
解决 Django 「懒惰」的基本方法
现在我们解决这个问题的方法就是「预加载」。从本质上讲,就是你提前警告 Django ORM 你要一遍又一遍的告诉它同样无聊的指令。在上面的例子中,在 DRF 开始获取前很简单地加上这句话就搞定了:
queryset = queryset.prefetch_related('orders')
当 DRF 调用上述相同序列化 customers 时,出现的是这种情况:
获取所有 customers (执行两个往返数据库操作,第一个是获取 customers,第二个获取相关 customers 的所有相关的 orders。)
对于第一个返回的 customers,获取其 order (不需要访问数据库,我们已经在上一步中获取了所需要的数据)
对于第二个返回的 customers,获取其 order (不需要访问数据库)
对于第三个返回的 customers,获取其 order (不需要访问数据库)
对于第四个返回的 customers,获取其 order (不需要访问数据库)
对于第五个返回的 customers,获取其 order (不需要访问数据库)
对于第六个返回的 customers,获取其 order (不需要访问数据库)
你又意识到,你可以有了 很多 customers ,已经不需要再继续等待去数据库。
其实 Django ORM 的「预备」是在第1步进行请求,它在本地高速缓存的数据能够提供步骤2+所要求的数据。与之前往返数据库相比从本地缓存数据中读取数据基本上是瞬时的,所以我们在有很多 customers 时就获得了巨大的性能加速。
解决 Django REST Framework 性能问题的标准化模式
我们已经确定了一个优化 Django REST Framework 性能问题的通用模式,那就是每当序列化查询嵌套字段时,我们就添加一个新的 @staticmethod 名叫 setup_eager_loading ,像这样:
class CustomerSerializer(serializers.ModelSerializer):
orders = OrderSerializer(many=True, read_only=True)
def setup_eager_loading(cls, queryset):
""" Perform necessary eager loading of data. """
queryset = queryset.prefetch_related('orders')
return queryset
这样,不管哪里要用到这个序列化,都只需在调用序列化前简单调用 setup_eager_loading ,就像这样:
customer_qs = Customers.objects.all()
customer_qs = CustomerSerializer.setup_eager_loading(customer_qs) # Set up eager loading to avoid N+1 selects
post_data = CustomerSerializer(customer_qs, many=True).data
或者,如果你有一个 APIView 或 ViewSet ,你可以在 get_queryset 方法里调用 setup_eager_loading :
def get_queryset(self):
queryset = Customers.objects.all()
# Set up eager loading to avoid N+1 selects
queryset = self.get_serializer_class().setup_eager_loading(queryset)
return queryset
结语:以上就是首席CTO笔记为大家整理的关于djangoorm如何优化的相关内容解答汇总了,希望对您有所帮助!如果解决了您的问题欢迎分享给更多关注此问题的朋友喔~