您还没有登录。现在登录注册

Django也会智能Lazyload?

分类: 编程   |   jeff  发表于:2007-09-19 00:00:44  |   88条评论  |

今天在本地很快实现了最新评论的功能。在右手边的最新评论点击连接时会去到文章的页面,并定位到评论所在的锚点上,也就是说,我需要在页面上取得评论所在文章的ID,也就是需要这样:{{comment.comment_to.id}}。这时候,我仅仅需要获得文章的ID,但不知道Django是否会到数据库去把相应的文章查出来(我没有使用Select_relate)之后再拿ID呢?不过Django好现没有可以设置打印执行Sql语句的开关,并不能通过配置来看到运行时Django查了多少次数据库。而这样的功能,我使用Java的Hibernate时就有的。

我Google了一下,发现Django本身是没有提供日志和Sql打印功能的。而有人做了些工作,如这位仁兄写了个中间件,可以在页面上打印出该次请求一共执行了多少条语句,每条语句的执行时间。而这里有个叫Django-logging的项目,为Django提供Logging,包括Sql的打印。等会就试验一下。Django天生就是Lazyload的,需要用到数据的时候才去加载,我希望,我的担心是多余的。一会尝试使用Log来看看测试结果吧。

结果一:Select_related对允许为空的外键不起作用。
我的查询语句是这样:entries = blog.entry_set.filter(status=1).select_related(depth=1).order_by('-id') 查询一个Blog下面所有的Entry,并把有关联的数据一并抓取出来(根据ForeignKey)。也就是说,在查询Entry的同时查出Blog,作者,分类等信息。
但是情况是,我在页面找印这些文章的时候,需要把文章的分类也打显示出来,这时候,Django却跑到数据库执行了N次查询分类的语句。暴汗。这是经典的Hibernate的延迟加载用得不恰当的情况啊!我一看打印出来的查询语句,有查相关的作者、Blog,但偏偏没有查分类。最后我回到Model里比较了一下,我的分类属性上面设置了null=true,原意是让文章可以没有分类。最后我尝试着去掉Null=true,一运行。那N条查询不见了。靠。。原来Select_related在外键允许空的情况下是行不通D。

结果二:Django不会智能LazyLoad。要手动去Select_related。
回到对Django有疑问的情景,recent_comments = Comment.objects.filter(blog=blog).order_by('-comment_time')[:10] 查出本BLog最新的十条评论。我的假设是,Comment本身保存有Entry的ID,所以在仅仅是获取Entry的ID的时候不需要去数据据里找,Hibernate的LazyLoad就是这样做的,使用动态代理的解决方案。我想在Python这样的动态语言的解决方案更佳,但事实证明我错了。上面的语句又产生了经典的1+N的问题。我在页面根据评论取EntryID的时候{{comment.entry.id}}还是去加载了一次数据,搞笑的是,这句查询需要得到的数据对我有用的是ID,但是查询条件就是ID。我只好把查询语句改成:
recent_comments = Comment.objects.select_related(depth=1).filter(blog=blog).order_by('-comment_time')[:10]。显示去Select_related。宁愿直接去Join相关的表,也不要做1+ N的查询。显然这很浪费,仅仅为了一个ID,要Join好几个表。

标签:django sql 日志 java hibernate orm 

评论(88条)

鳄鱼 在2007-09-21说:RE:Django也会智能Lazyload?

是不是在comment表里在存储一个entryID,这样comment.entryID可以直接取到,而不用去join Entry表

当要取entry的title时,用显示的select_related来完成

杰夫 在2007-09-22说:RE:Django也会智能Lazyload?

Comment表里本来就有一个Entry_id,再加一个EntryID同样性质的字段显得浪费了。而且没什么意义。

elo 在2008-01-29说:RE:Django也会智能Lazyload?

楼上的说的对,不要去取comment.entry.id,而是取comment.entry_id就可以解决这个问题了。



(可不填)



 = 

站内搜索

作者简介

jeff

一身不由已的前developer, 狂爱音乐,篮球,现习詠春.现在看见别人写代码就流口水,转而效阿Q曰:我在编写生活的代码.不管做什么,全力以赴!到这里看我都在发些什么牢骚.

mail
qq

赞助商链接

唠叨些啥捏

friends connect

我看我听我读

都有谁评论鸟

Tags

python 朋友 音乐 工作 django 生活 java 旅游 丽江 云南 编程 空间 javascript 摇滚 apple air 年假 2008 中国 google mac apache 主机 ajax grails 技术 健康 部署 学习 更新 web 互联网 gfw 乐队 ext 灾难 感情 flex jmesa 哀悼日 灾害 jquery beautifulSoup 感悟 flash 体验 开源 卖唱 plone 软件管理 数据库 电影 恐怖 诗歌 计划 原创 开发 orm sql 全文搜索 lucene 发呆 2009 管理 随想 大理 免费 mozilla 感性 香格里拉 休假 firefox 鼻炎 许巍 php 网络 AMF actionscript 汉诺塔 算法 递归 结婚 opensource htmlparse mindnode mindmap 技巧 blogspot url prototpye cpug 在线服务 嵌入式 海鲜 thing p2p easymule codeigniter 休眠 caffeine 英语 翻译 gtd task vpn 穿墙 手机仿真 经济 聚会 出差 prism 搬家 北京 api 创业 商城 blackberry 手机 TD 交流 处事 为人 房子 代理 西片 中文分词 模板 分页 成功 pagerank 中文 个性化 秋天 json 事业 职业 读书 香港 澳门 忧郁 函数式编程 并发 惊变 mysql rss 文艺片 太阳 彩色 factcgi lighttpd editor MYMeditor 日志 hibernate 英伦 中间件 erlang 冬天 compass dvd 需求 设计 信息 人生 真诚 life 杭州 捐赠 scrum 软件过程 快速开发 cms nuexo zope 左小诅咒 ria 遇窃 广州 地下 暴力 美学 声音玩具 独立 备份 数据 琐事 博客 接口 设计模式 图表 wiki moin demo

日志分类

友情连接

Power By