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的更多相关文章

  1. 手撸ORM浅谈ORM框架之Delete篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  2. 手撸ORM浅谈ORM框架之基础篇

    好奇害死猫 一直觉得ORM框架好用.功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! ...

  3. 手撸ORM浅谈ORM框架之Add篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  4. 手撸ORM浅谈ORM框架之Update篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  5. 手撸ORM浅谈ORM框架之Query篇

    快速传送 手撸ORM浅谈ORM框架之基础篇 手撸ORM浅谈ORM框架之Add篇 手撸ORM浅谈ORM框架之Update篇 手撸ORM浅谈ORM框架之Delete篇 手撸ORM浅谈ORM框架之Query ...

  6. 手撸orm

    ORM简介 ORM即Object Relational Mapping,全称对象关系映射.当我们需要对数据库进行操作时,势必需要通过连接数据.调用sql语句.执行sql语句等操作,ORM将数据库中的表 ...

  7. 康少带你玩转JavaScript

    目录 1.JavaScript简述 2.JavaScript引入方式 3.JavaScript语法基础 4.JavaScript数据类型 5.运算符 6.流程控制 7.函数 8.内置对象和方法 1.J ...

  8. 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...

  9. 康少带你python项目从部署到上线云服务器

    首先,服务器要安装nginx和mysql,网站文件建议放在/usr/local/www,环境python3.6+mysql5.7,阿里云的服务器可以用公共镜像有一个配置好的,不然就自己装一下环境吧. ...

随机推荐

  1. 时间操作(Java版)—获取给定日期N天后的日期

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wangshuxuncom/article/details/34896777         获取给定 ...

  2. linux内核驱动中对文件的读写 【转】

    本文转载自:http://blog.chinaunix.net/uid-13059007-id-5766941.html 有时候需要在Linux kernel--大多是在需要调试的驱动程序--中读写文 ...

  3. 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 ...

  4. 关于URL编码的一些结论

    转载自:http://www.ruanyifeng.com/blog/2010/02/url_encoding.html与http://www.ruanyifeng.com/blog/2007/10/ ...

  5. Struts2 Action 匹配的几种方式

    下面针对我所遇见的Action的配置方法进行一下总结: 1.基本的匹配方法

  6. CISCO-从路由器上下载IOS

    准备工作:一台装有TFTP服务器的PC,一台带有IOS的路由器,并用网线连接上 设置路由器接口和计算机网卡的IP地址在同一网段,并且互相能ping通. 1,安装Cisco TFTP Server 2, ...

  7. 使用diskpart命令修复U盘分区

    前段时间在论坛上讨论封装PE到u盘里热闹的,就想自己也封装一个,随便下载了一个WIN7的PE封装后发现还不错,本来就是做测试用的,测试完了就想把u盘在恢复成以前的样子,可是发现恢复并不是这么容易 如下 ...

  8. 记录一个读pcap数据包的软件:Fiddler

    Fiddler.大神推荐的.名字老忘. 用wireshark在wifi共享精灵共享出来的无线网上抓包,发现一个SSDP(简单服务发现协议)一直在尝试找连上这个网络上的设备. 连上NEXUS4后出现了I ...

  9. bzoj 2151 种树——贪心+后悔

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151 似乎是半年+前讲过的.(然而看到的时候却不会了) 考虑贪心,限制就是不能选两边的.如果 ...

  10. ubuntu系统,关于源(source)的配置

    1. 现象:(出现的错误) 执行 sudo apt-get update, 报错:apt-get 404 Not Found Package Repository Errors 执行 sudo apt ...