django model filter_Django分表的两个方案
由来
知乎上的一个问题:Django 分表 怎么实现?
这个问题戳到了Django ORM的痛点,对于多数据库/分库的问题,Django提供了很好的支持,通过using和db router可以很好的完成多数据库的操作。但是说到分表的问题,就有点不那么友好了。但也不是那么难处理,只是处理起来不太优雅。
解析
在Django中,数据库访问的逻辑基本上是在Queryset中完成的,一个查询请求,比如:User.objects.filter(group_id=10)。
其中的objects其实就是models.Manager,而Manager又是对QuerySet的一个包装。而QuerySet又是最终要转换为sql的一个中间层(就是ORM种,把Model操作转换为SQL语句的部分)。所以当我们写下User.objects的时候,就已经确定了要访问的是哪个表了,这是由class Meta中的db_table决定的。
class
理论上讲,我们可以通过在运行时修改db_table来完成分表CRUD的逻辑,但是the5fire在看了又看源码之后,还是没找到如何下手。还是上面的问题,当执行到User.objects的时候,表已经确定了,当执行到User.objects.filter(group=10)的时候只不过是在已经生成好的sql语句中增加了一个where部分语句。所以并没有办法在执行filter的时候来动态设置db_table。
对于问题中说的get也是一样,因为get本身就是在执行完filter之后从_result_cache列表中获取的数据(_result_cache[0])。
方案一
根据the5fire上面的分析,要想在执行具体查询时修改db_table已经是不可能了(当然,如果你打算去重写Model中Meta部分的逻辑以及Queryset部分的逻辑,就当我没说,我只能表示佩服)。
所以只能从定义层面下手了。也就是我需要定义多个Model,同样的字段,不同的db_table。大概是这样。
class
这样在User.objects.get(id=3)的时候,如果按照模2计算,那就是User01.objects.get(id=3),笨点的方法就是写一个dict:
user_sharding_map
如果真的这么写那Python作为动态语言,还有啥用,你分128张表试试。我们应该动态创建出User01,User02,....UserN这样的表。
class
嗯,这样看起来似乎好了一下,但是还有问题,id=3需要传两次,如果两次不一致,那就麻烦了。Model层要为上层提供统一的入口才行。
class MyUser(models.Model):# 增加方法 BY the5fire@classmethoddef sharding_get(cls, id=None, **kwargs):assert id, 'id is required!'Model = cls.get_sharding_model(id=id)return Model.objects.get(id=id, **kwargs)
对上层来书,只需要执行MyUser.sharding_get(id=10)即可。不过这改变了之前的调用习惯 objects.get 。
不管怎么说吧,这也是个方案,更完美的方法就不继续探究了,在Django的ORM中钻来钻去寻找可以hook的点实在憋屈。
我们来看方案二吧
方案二
ORM的过程是这样的,Model——> SQL ——> Model,在方案一中我们一直在处理Model——> SQL的部分。其实我们可以抛开这一步,直接使用raw sql。
QuerySet提供了raw这样的接口,用来让你忽略第一层转换,但是有可以使用从SQL到Model的转换。只针对SELECT的案例:
class
大概这么个意思吧,代码可以再严谨些。
总结
单纯看方案一的话,可能会觉得这么大量数据的项目,就别用Django了。其实the5fire第一次尝试找一个优雅的方式hack db_table时,也是一头灰。但是,所有的项目都是由小到大的,随着数据/业务的变大,技术人员应该也会更加了解Django,等到一定阶段之后,可能发现,用其他更灵活的框架,跟直接定制Django成本差不多。
补充两个github repo: - JBKahn/django-sharding - disqus/sharding-example
----EOF-----
扫码关注,或者搜索微信公众号:Python程序员杂谈
django model filter_Django分表的两个方案相关推荐
- django全自动分库分表(横向)
django全自动分库分表 期待大神指点方法的不足之处或者其他更好的方法 由于当前项目目前只需要实现写,所以这里也没有考虑读写分离.如果要考虑读写分离,则在路由处进行设置即可. 分库原理 django ...
- 架构组件:基于Shard-Jdbc分库分表,数据库扩容方案
架构组件:基于Shard-Jdbc分库分表,数据库扩容方案 一.数据库扩容 1.业务场景 互联网项目中有很多"数据量大,业务复杂度高,需要分库分表"的业务场景. 这样分层的架构 ( ...
- django model filter_Django开发常用方法及面试题
Django开发常用方法及面试题 目录 1. 对Django的认识? 2. Django .Flask.Tornado的对比 3. 什么是wsgi,uwsgi,uWSGI? 4. django请求的生 ...
- 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...
文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...
- MySQL 分库分表及其平滑扩容方案
作者:王克锋 出处:https://kefeng.wang/2018/07/22/mysql-sharding/ 众所周知,数据库很容易成为应用系统的瓶颈.单机数据库的资源和处理能力有限,在高并发的分 ...
- 数据库调优过程(五):物理分表,及写入方案调整
背景: enb下包含多个文件,我们需要解析这样的数据到数据库中,供应用端计算分析使用.之前,我们已经采用了分表方案,分表分为一个主表,三个子表.每一个enb一套表. 解析业务: 每取到一个文件就读取为 ...
- MySQL关于分库分表及其平滑扩容方案
众所周知,数据库很容易成为应用系统的瓶颈.单机数据库的资源和处理能力有限,在高并发的分布式系统中,可采用分库分表突破单机局限.本文总结了分库分表的相关概念.全局ID的生成策略.分片策略.平滑扩容方案. ...
- 分库分表技术及技术方案
一.分库分表的必要性 分库分表技术的使用,主要是数据库产生了瓶颈,如单库的并发访问或单表的查询都超出了阈值.对系统使用造成一定的影响,不得已而产生的技术. 通过分库分表技术来解决此类问题,但正因为使用 ...
- postgresql分库分表中间件开源实现方案
PostgreSQL 分库分表的中间件开源实现方案有很多, 你可以根据自己的需要选择适合自己的方案. 下面是几种常见的方案: pgpool-II: 一个 PostgreSQL 透明数据库代理, 具有负 ...
最新文章
- socket编程报异常java.io.EOFException
- python比较好的书籍推荐-推荐几本2019年初学者学习Python最佳书籍!
- php和python区别-PHP与Python语言有哪些区别之处?选择哪一个好?
- 第12章:项目采购管理(2)-章节重点
- OPPO尝鲜android版本更新,安卓11迎来四大贴心升级,OPPO小米率先尝鲜
- OpenCV gapi模块OMZ文本检测的实例(附完整代码)
- Python之——遇到的小知识点总结
- IPython快捷键及命令
- C#开发笔记之11-如何用C#过滤连续相同的字符串?
- 非局部均值(Nonlocal-Mean)
- FineReport:任意时刻只允许在一个客户端登陆账号的插件
- 【李宏毅机器学习】Logistic Regression 逻辑回归(p11) 学习笔记
- php7 viewmodel,ViewModel浅析
- SQLServer导数据到Oracle
- nginx+lua搭建文件上传下载服务
- VS2010-MFC(Ribbon界面开发:为Ribbon Bar添加控件)
- Java Access Bridge
- 杭电acm--2154跳舞毯
- quartz 每月一次_quartz cron表达式 每周一0点怎么设置
- Anmle,Factors,andMultiFactorModels
热门文章
- jquery判断多选框是否选中
- 三个斯坦福华裔学生,送外卖成亿万富翁
- 写给初学者的Tensorflow介绍
- vector使用排序函数实例
- base64的c语言实现方法
- java百度云推送demo_百度云推送java服务端maven安装完整demo
- 文件内容查找java,java库从文件内容中查找mime类型
- 约瑟夫环java链表_java使用链表实现约瑟夫环
- excel字符串和单元格拼接_Excel实例分享-学会输入数据小技巧,让你的工作效率远超同事...
- 服务中没有listen_Go语言微服务框架实战:2.Go语言实现RPC编程绍