"""
ORM思路归纳: 1、将每张表映射成不同的表类,一个表类映射一张表。表类的类属性
需要有表名、字段名
将每个字段类型映射为字段类型类,一个字段类型类映射一个类
字段类实例化需要传入有字段名、字段类型、是否是主键、默认值
等参数,其中除字段名外其他参数可设置默认值
2、每个表类都有相同的基础属性,如表名,主键字段,增删改查方法,
那么由此就可以抽离出Models基类,相同属性和方法同一抽到基类,
不涉及需要每个表区别属性的方法我们把它抽为基类类方法。
3、考虑到一条数据库数据需要产生一个对象,用pymysql查询得到得可以
是字典类型,那么我们可以将基类Models继承dict,用__setattr__
将字段转换为伪对象属性操作,用__getattr__对属性取值
由基类查询一条或者多条数据的类方法,将得到的记录本身传给表类
自身实例化得到对象,用__setattr__将字段作为对象属性,这样一
个对象就可以映射一条数据
4、为了更好的实现对数据库表的映射,我们需要创建元类来对定义的表类
的控制,如一个表只且只有一个主键,规范每个表类的属性名称,比如
表名、主键名,其他字段集合
5、另外要实现对数据库操作提交,这部分功能不适合做在基类表类中,做在
表类中会让表类臃肿且逻辑不清,我们将其专门定义一个数据库连接类,
表这一部分就负责实现功能,具体对数据库通信操作由数据库连接类去完成 """ # 实现代码 class Field(object):
"""
Field:映射数据库字段 基类
name:字段名
culomn_type:字段类型
primary_key:是否是主键
default:默认值
"""
def __init__(self,name,culomn_type,primary_key,default):
self.name = name
self.culomn_type = culomn_type
self.primary_key = primary_key
self.default = default class IntField(Field):
"""
继承Field基类,实现对int类型字段的映射
"""
def __init__(self,name,culomn_type = "int",primary_key = False,default = 0):
super().__init__(name,culomn_type,primary_key,default) class PrimaryField(Field):
"""
继承Field基类,实现对主键字段的映射
"""
def __init__(self,name,culomn_type,primary_key = True, default = None):
super().__init__(name,culomn_type,primary_key,default) class StringField(Field):
"""
继承Field基类,实现对char类型字段的映射
"""
def __init__(self,name,culomn_type = "varchar(64)", primary_key = False,default = ""):
super().__init__(name,culomn_type,primary_key,default) # 你还可以继续定义其他类型字段类,如日期等 class MyMeta(type):
"""
自定义元类,实现对每张表映射的表类的属性控制
如:1、限制一个表有且只能有一个主键,否则创建派生类失败
2、将表的字段属性全部放到一个字典里,然后把这个字典整体放入类的名称空间
"""
def __new__(cls, class_name, class_bases, class_space): # 控制类产生
if class_name == "Models": # 对 Models类不生效
# 所有表类由Models类派生
return type.__new__(cls,class_name,class_bases, class_space) table_name = class_space.get("table_name")
primary_key = None
mappings = {}
for k,v in class_space.items():# 筛选出主键
if isinstance(v,Field):
mappings[k] = v
if v.primary_key:
if primary_key:
raise TypeError("一个表只能有一个主键")
primary_key = v
for key in mappings.keys(): # 将原名称空间中的所有字段属性删除
class_space.pop(key) class_space["table_name"] = table_name
class_space["primary_key"] = primary_key # 将筛选出来的属性重新装回类名称空间
class_space["mappings"] = mappings # 将字段属性装入mapping再装回原名称空间 return type.__new__(cls,class_name,class_bases,class_space) # 调回type__new__ class Models(dict,metaclass = MyMeta):
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): # 查询表单条或多条记录,并实例化记录为对象返回
mysql = Mysql.create_instance()
if not kwargs:
sql = "select * from %s"%cls.table_name
res = mysql.select(sql)
else:
k = list(kwargs.keys())[0]
v = kwargs.get(k)
sql = "select * from %s where %s = $"%(cls.table_name,k)
sql = sql.replace("$","%s")
res = mysql.select(sql,(v,))
if res:
return [cls(**r) for r in res] import pymysql
class Mysql(object) :
_instance = None
def __init__(self): # 建立数据库连接
self.conn = pymysql.connect(
host = "127.0.0.1",
port = 3306,
user = "root",
password = "",
database = "class",
charset = "utf8",
autocommit = True
)
self.cursor = self.conn.cursor(pymysql.cursors.DictCursor) # 设置查询返回数据格式为列表套字典 @classmethod
def create_instance(cls): # 创建单例
if not cls._instance:
cls._instance = cls()
return cls._instance def select(self,sql,arg = None): # 提交数据库操作
if not arg:
try:
self.cursor.execute(sql)
except BaseException as e:
print(e)
return
else:
try:
self.cursor.execute(sql,arg)
except BaseException as e:
print(e)
return
res = self.cursor.fetchall() # 拿到所有返回结果
return res if __name__ == '__main__':
class Course(Models): # course表类
table_name = "course"
cid = PrimaryField(name = "cid",culomn_type="int") # 表id字段 创建主键字段对象
cname = StringField(name = "cname") # 表cname字段,创建字符串类型对象 res = Course.select(cid = 3) # 查找cid = 3的记录并实例化对象返回
print(res[0].cname)
print(res[0].mappings)

python 其实不用框架你也可以实现ORM的更多相关文章

  1. python的Web框架,Django的ORM,模型基础,MySQL连接配置及增删改查

    Django中的ORM简介 ORM概念:对象关系映射(Object Relational Mapping,简称ORM): 用面向对象的方式描述数据库,去操作数据库,甚至可以达到不用编写SQL语句就能够 ...

  2. Python 并行分布式框架 Celery

    Celery 简介 除了redis,还可以使用另外一个神器---Celery.Celery是一个异步任务的调度工具. Celery 是 Distributed Task Queue,分布式任务队列,分 ...

  3. 谈谈Python中元类Metaclass(二):ORM实践

    什么是ORM? ORM的英文全称是“Object Relational Mapping”,即对象-关系映射,从字面上直接理解,就是把“关系”给“对象”化. 对应到数据库,我们知道关系数据库(例如Mys ...

  4. 【转】Python 并行分布式框架 Celery

    原文链接:https://blog.csdn.net/freeking101/article/details/74707619 Celery 官网:http://www.celeryproject.o ...

  5. Python之Web框架Django

    Python之Web框架: Django 一. Django Django是一个卓越的新一代Web框架 Django的处理流程 1. 下载地址  Python 下载地址:https://www.pyt ...

  6. Python 常用Web框架的比较

    转载来自:https://www.cnblogs.com/sunshine-1/p/7372934.html 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OL ...

  7. python各种web框架对比

    0 引言        python在web开发方面有着广泛的应用.鉴于各种各样的框架,对于开发者来说如何选择将成为一个问题.为此,我特此对比较常见的几种框架从性能.使用感受以及应用情况进行一个粗略的 ...

  8. python+selenium+unnittest框架

    python+selenium+unnittest框架,以百度搜索为例,做了一个简单的框架,先看一下整个项目目录结构 我用的是pycharm工具,我觉得这个工具是天使,超好用也超好看! 这些要感谢原作 ...

  9. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

随机推荐

  1. Educational Codeforces Round 33 (Rated for Div. 2) C题·(并查集变式)

    C. Rumor Vova promised himself that he would never play computer games... But recently Firestorm — a ...

  2. 微信小程序开发入门教程(四)---自己动手做个小程序

    前面已将基础知识准备的差不多了,下面实际做一个小程序. 一.目标 用于上传照片和文字. 2个主要页面:我me,设置set 二.开始制作 1.打开微信开发者工具(我用的1.02.1907160 Wind ...

  3. [Luogu] 次小生成树

    https://www.luogu.org/problemnew/show/P4180#sub 严格次小生成树,即不等于最小生成树中的边权之和最小的生成树 首先求出最小生成树,然后枚举所有不在最小生成 ...

  4. 字符串匹配问题x

    qwq这个是栈的w   不是树w   qwq我承认我发题很杂啦   字符串匹配问题x [问题描述]        字符串中只含有括号 (),[],<>,{},判断输入的字符串中括号是否匹配 ...

  5. 利用Python构建时间序列模型解决实际问题的正确姿势

    要本着应用到实际工作中目的去学时间序列分析,才能深入浅出的学会,不要纠结于理论,只听我的,我有信心说明白. 本章内容 趋势分析 序列分解 序列预测 序列分解 统计学基础铺垫 划分 时间序列按照季节性划 ...

  6. [Linux]安装kali虚拟机后忘记root密码

    1. 登录时,按e进入编辑模式 2. 编辑模式 修改 ro 修改为 rw 添加 init=/bin/bash 修改完按 F10 3. 选择recovery mode 回车 4.输入命令passwd 设 ...

  7. JavaWeb_(Mybatis框架)使用Mybatis对表进行增、删、改、查操作_二

    系列博文: JavaWeb_(Mybatis框架)JDBC操作数据库和Mybatis框架操作数据库区别_一 传送门 JavaWeb_(Mybatis框架)使用Mybatis对表进行增.删.改.查操作_ ...

  8. Rhel7.4系统部署cobbler

    cobbler安装 一.系统信息: [root@openstack ~]# cat /etc/redhat-release Red Hat Enterprise Linux Server releas ...

  9. LVS集群之IP TUN模式以及网站压力测试

    今天来看一下LVS的第三种模式IP TUN. TUN方式,是通过给数据包加上新的IP头部来实现,这个可以跨整个广域网. 环境: 主机名 IP 系统 角色 tiandong63 RIP:192.168. ...

  10. linux下通过进程名查看其占用端口

    linux下通过进程名查看其占用端口: 1.先查看进程pid ps -ef | grep 进程名 2.通过pid查看占用端口 netstat -nap | grep 进程pid 例:通过nginx进程 ...