V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Veigar
V2EX  ›  Python

Django ORM QuerySet lazy loading(懒加载) 是如何实现的?原理为何?

  •  
  •   Veigar · 2017-07-08 13:03:25 +08:00 · 4164 次点击
    这是一个创建于 2476 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如说  books = Book.objects.all()
    这一行代码并不会在运行时就取出所有数据
    而是要到真正使用 books 时才会去取出数据
    怎么做到的呢?原理是什么?
    
    5 条回复    2017-07-12 01:13:05 +08:00
    ss098
        1
    ss098  
       2017-07-08 16:25:45 +08:00
    可能是魔术方法。
    SP00F
        2
    SP00F  
       2017-07-08 23:32:24 +08:00
    Django 不熟,是异步吗 ……
    Morriaty
        3
    Morriaty  
       2017-07-11 13:26:58 +08:00
    没看过源码,我想到的一种可能实现是:
    1、all()只是编译好了 sql,但没执行
    2、orm object 的__iter__()方法才是真执行 sql

    大致逻辑:

    class ORMObject(object):
    def all(self):
    self.sql = ....
    return self

    def filter(self, condition):
    self.sql = ....
    return self

    def __iter__(self):
    self.execute()
    Morriaty
        4
    Morriaty  
       2017-07-11 13:27:57 +08:00
    哇 v 站评论不支持 markdown 也就罢了,还自动删减空格.........
    daya0576
        5
    daya0576  
       2017-07-12 01:13:05 +08:00 via iPad
    楼上正解, 在执行这些魔术方法的时候去执行的 sql 并生成缓存:
    Iteration, ie. 对 Queryset 进行 For 循环的操作.
    slicing, e.g. Entry.objects.all()[:5], 获取 queryset 中的前五个对象, 相当于 sql 中的 LIMIT 5
    picling/caching
    repr/str
    len (Note: 如果你只想知道这个 queryset 结果的长度的话, 最高效的还是在数据库的层级调用 count()方法, 也就是 sql 中的 COUNT(). )
    list()
    bool()

    但调 queryset[5], values_list(), iterator()也会触发执行 sql, 但没有 cache 生成。

    参考我的笔记: https://changchen.me/blog/20170503/django-performance-and-optimisation/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1220 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:23 · PVG 07:23 · LAX 16:23 · JFK 19:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.