康少带你手撸orm
orm
什么是orm?
对象关系映射:
一个类映射成一张数据库的表
类的对象映射成数据库中的一条条数据
对象点数据映射成数据库某条记录的某个值
优点:不会写sql语句的程序员也可以很6的操作sql语句,大大的提升了开发效率
缺点:sql语句的效率不是很高
手撸orm具体代码
from orm_singleton.mysql_singleton import Mysql # 表的字段通常需要有的属,字段类性字段名型,是否是主键,默认值
class Field(object):
def __init__(self,name, column_type, primary_key, default):
self.name = name
self.column_type = column_type
self.primary_key = primary_key
self.default = default # 定义varchar字段类型
class StringField(Field):
def __init__(self, name, column_type='varchar(255)', primary_key=False, default=None):
super().__init__(name,column_type,primary_key,default) # 定义int字段类型
class IntegerField(Field):
def __init__(self, name, column_type='int', primary_key=False, default=0):
super().__init__(name, column_type, primary_key, default) # 它是用来拦截跟数据库中表对应的类的创建
class MyMetaClass(type):
def __new__(cls, class_name, class_bases, class_attrs):
# 我们定义的元类是用来拦截模型表的创建过程,而models并不是一张模型表,所以不需要它的创建过程
if class_name == 'Models':
return type.__new__(cls,class_name,class_bases,class_attrs)
table_name = class_attrs.get('table_name',class_name)
primary_key = None
mappings = {}
# 下面的for循环需要做两件事
# 1.将单个单个的字段整合成一个
# 2.确定当前表当地哪个字段是主键
for k,v in class_attrs.items(): # k:id,name v:IntegerField(),StringField()
# 拿出所有自己定义的表的字段属性
if isinstance(v,Field):
# 将所有的自己定义的表的字段存入字典中
mappings[k] = v
if v.primary_key:
# 健壮性校验一张表不能有多个主键
if primary_key:
raise TypeError("一张表只能有一个主键")
primary_key = v.name
# 循环mapping拿到所有的自定义字段名
for k in mappings.keys():
# 将单个单个的字段删除
class_attrs.pop(k)
# 校验用户自定义的模型表是否指定了主键字段
if not primary_key:
raise TypeError("一张表必须要有主键")
# 将标示表的特征信息 表名,表的主键字段,表的其他字段都塞到类的名称空间中
class_attrs['table_name'] = table_name
class_attrs['primary_key'] = primary_key
class_attrs['mappings'] = mappings
return type.__new__(cls, class_name, class_bases, class_attrs) class Models(dict, metaclass=MyMetaClass):
def __init__(self, **kwargs):
super().__init__(**kwargs) def __getattr__(self, item):
return self.get(item,'没有该键!') def __setattr__(self, key, value):
self[key] = value @classmethod
def select(cls,**kwargs): # id=1,name='jason',password='123'
ms = Mysql()
# select * from %s
if not kwargs:
sql = "select * from %s"%cls.table_name
res = ms.select(sql)
else:
# select * from %s where %s=%s
k = list(kwargs.keys())[0]
v = kwargs.get(k)
sql = "select * from %s where %s=?"%(cls.table_name,k) # select * from user where id=?
sql = sql.replace('?','%s') # select * from user where id=%s
res = ms.select(sql,v)
if res:
# res = [{},{},{}]
# cls(name='...',password='...')
return [cls(**r) for r in res] # [obj1,obj2,obj3] def update(self):
ms = Mysql()
# update user set name='jason',password='123' where id = 1
# update user set name=%s,password=%s where id = 1
# 定义一个列表存储该表的所有字段名
fields = []
# 定义一个变量用来存储当前数据对象的主键值
pr = None
values = []
for k,v in self.mappings.items():
# 先把当前数据对象对应的主键值拿到
if v.primary_key:
pr = getattr(self,v.name,v.default)
else:
# 除了主键之外的所有字段
fields.append(v.name+'=?') # [name=?,password=?...]
values.append(getattr(self,v.name,v.default)) sql = "update %s set %s where %s=%s"%(self.table_name,','.join(fields),self.primary_key,pr)
# update user set name=?,password=? where id=1
sql = sql.replace('?','%s')
# update user set name=%s,password=%s where id=1
ms.execute(sql,values) def save(self):
ms = Mysql()
# insert into user(name,password) values('zhaokang','123')
fields = []
# 专门用来存储与字段对应数量的?
args = []
values = []
for k,v in self.mappings.items(): # name:StringField(name='name')
if not v.primary_key: # 将id字段去除 因为id字段是自增,不需要人为的去操作
fields.append(v.name)
args.append('?')
values.append(getattr(self,v.name,v.default))
sql = "insert into %s(%s) values(%s)"%(self.table_name,','.join(fields),','.join(args))
# insert into user(name,password) values(?,?)
sql = sql.replace("?",'%s')
# insert into user(name,password) values(%s,%s)
ms.execute(sql,values)
pool数据库连接池
from DBUtils.PooledDB import PooledDB
import pymysql POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
maxshared=3,
# 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
host='127.0.0.1',
port=3306,
user='root',
password='admin',
database='youku',
charset='utf8',
autocommit='True'
)
pymysql连接数据库
import pymysql
from orm_pool.pool import POOL class MySQL(object):
def __init__(self):
self.conn = POOL.connection()
self.cursor =self.conn.cursor(pymysql.cursors.DictCursor) # def colse_conn(self):
#
# self.conn.close()
# self.cursor.close() def select(self,sql,args=None):
self.cursor.execute(sql,args)
res = self.cursor.fetchall()
return res def execute(self,sql,args=None):
try:
self.cursor.execute(sql, args)
except BaseException as e:
print(e)
测试orm
首先必须在自己的数据库建立一张表比如:
这张表我只是简单的举一个例子而已 你们也可以设计自己的表只需要在Filed中添加字段就行
if __name__ == '__main__':
class Teacher(Models):
table_name = 'teacher' #表的名字
tid = IntegerType(name='tid', primary_key=True) # IntegerType实例化出的对象
tname = StringType(name='tname') # StringType实例化出的对象 data_list = Teacher.select(tname='仓老师') #查
user_obj = data_list[0]
print(user_obj)
user_obj.tname = '波老师' # 改
user_obj.update()
user = Teacher(tname='小泽老师') #增
user.save()
print(user)
康少带你手撸orm的更多相关文章
- 手撸ORM浅谈ORM框架之Delete篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之基础篇
好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...
- 手撸ORM浅谈ORM框架之Add篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Update篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸ORM浅谈ORM框架之Query篇
快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...
- 手撸orm
ORM简介 ORM即Object Relational Mapping,全称对象关系映射.当我们需要对数据库进行操作时,势必需要通过连接数据.调用sql语句.执行sql语句等操作,ORM将数据库中的表 ...
- 康少带你玩转JavaScript
目录 1.JavaScript简述 2.JavaScript引入方式 3.JavaScript语法基础 4.JavaScript数据类型 5.运算符 6.流程控制 7.函数 8.内置对象和方法 1.J ...
- 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...
- 康少带你python项目从部署到上线云服务器
首先,服务器要安装nginx和mysql,网站文件建议放在/usr/local/www,环境python3.6+mysql5.7,阿里云的服务器可以用公共镜像有一个配置好的,不然就自己装一下环境吧. ...
随机推荐
- 时间操作(Java版)—获取给定日期N天后的日期
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wangshuxuncom/article/details/34896777 获取给定 ...
- linux内核驱动中对文件的读写 【转】
本文转载自:http://blog.chinaunix.net/uid-13059007-id-5766941.html 有时候需要在Linux kernel--大多是在需要调试的驱动程序--中读写文 ...
- TP框架中的多种方法代码(C,G,L,T,I,N,D,M,A,R,B,U,W,S,F,E)
C方法 function C($name=null, $value=null,$default=null) { static $_config = array(); // 无参数时获取所有 if (e ...
- 关于URL编码的一些结论
转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html与http://www.ruanyifeng.com/blog/2007/10/ ...
- Struts2 Action 匹配的几种方式
下面针对我所遇见的Action的配置方法进行一下总结: 1.基本的匹配方法
- CISCO-从路由器上下载IOS
准备工作:一台装有TFTP服务器的PC,一台带有IOS的路由器,并用网线连接上 设置路由器接口和计算机网卡的IP地址在同一网段,并且互相能ping通. 1,安装Cisco TFTP Server 2, ...
- 使用diskpart命令修复U盘分区
前段时间在论坛上讨论封装PE到u盘里热闹的,就想自己也封装一个,随便下载了一个WIN7的PE封装后发现还不错,本来就是做测试用的,测试完了就想把u盘在恢复成以前的样子,可是发现恢复并不是这么容易 如下 ...
- 记录一个读pcap数据包的软件:Fiddler
Fiddler.大神推荐的.名字老忘. 用wireshark在wifi共享精灵共享出来的无线网上抓包,发现一个SSDP(简单服务发现协议)一直在尝试找连上这个网络上的设备. 连上NEXUS4后出现了I ...
- bzoj 2151 种树——贪心+后悔
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151 似乎是半年+前讲过的.(然而看到的时候却不会了) 考虑贪心,限制就是不能选两边的.如果 ...
- ubuntu系统,关于源(source)的配置
1. 现象:(出现的错误) 执行 sudo apt-get update, 报错:apt-get 404 Not Found Package Repository Errors 执行 sudo apt ...