python自定义ORM并操作数据库
看这个代码之前先去看上篇文章,理解type的用法及元类的含义:
ORM可以代替pymysql,实现将python语义装换为sql语句,简单化
import pymysql
'''
metaclass,直译为元类,简单的解释就是:
当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。
但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。
连接起来就是:先定义metaclass,就可以创建类,最后创建实例。
所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。
当我们传入关键字参数metaclass时,魔术就生效了,它指示Python解释器在创建Student时,
要通过ModelMetaClass.__new__()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。
'''
class Field(object):#定义一个字段类
def __init__(self,name,column_type):
self.name = name#字段名
self.column_type = column_type#字段类型
def __str__(self):
return "<%s:%s>"%(self.name,self.column_type)
class StringField(Field):#字符串类型字段,继承Field
def __init__(self,name):
super(StringField,self).__init__(name,"varchar(100)")
# super(StringField, self).__init__(name,char(20))
class IntegerField(Field):#数字类型字段,继承Field
def __init__(self,name):
super(IntegerField,self).__init__(name,"int")
class ModelMetaClass(type):#定义一个元类
def __new__(cls, name,bases,attrs):
'''
:param name: 类的名称
:param bases: 类的继承
:param attrs: 类的属性
:return:
'''
if name == "Model":#如果传入的name:类名为Model则不进行操作,直接返回type类的相关参数
return type.__new__(cls,name,bases,attrs)
# return super(ModelMetaClass, self).__new__(cls,name,bases,attrs)
print('Found model: %s' % name) # 打印当前实例的类名称
mapping = dict() #空字典
for k,v in attrs.items(): #遍历属性
print('key:%s,value:%s' % (k, v))#打印遍历attrs的key和value
if isinstance(v,Field): #判断属性是否Field的实例
mapping[k] = v #添加到mapping当中
# print(mapping)
for k in mapping.keys(): #返回所有键
attrs.pop(k) #mapping里存在的内容从属性当中删除
attrs["__mapping__"] = mapping #设定__mapping__属性来保存字段
attrs["__table__"] = name #设定类名和表名一致(不区分大小写)
# print(attrs)
return type.__new__(cls,name,bases,attrs)#返回给类实例,这里为Student
class Model(dict,metaclass = ModelMetaClass):#创建一个实例类,设置其元类
def __init__(self,**kwargs):
self.db = pymysql.connect(#链接数据库
host = "localhost",
user = "root",
password = "123",
database = "test"
)
self.cursor = self.db.cursor()
super(Model,self).__init__(**kwargs)
def __getattr__(self, key):
return self[key]#返回对象的属性值
# print(self[key])
def __setattr__(self, key, value):
self[key] = value#设置对象的属性及其对应的值
def save(self):
fields = [] #空列表用来存储字段
args = [] #空列表用来存储字段的值
for k,v in self.__mapping__.items():
fields.append(v.name)#此时,v为field子类的实例,因此可以取出类属性name,作为字段名
# print(getattr(self, k, None))
args.append(getattr(self,k,None))#此时调用了self,则将传入的参数调用,此时再取变量的值,则为传入的实参
sql = "insert into %s(%s) values (%s)"%(
self.__table__,
",".join(fields),
",".join([repr(str(i)) for i in args]
)) #sql拼接
self.cursor.execute(sql)
print(sql)
def __del__(self):
'''
回收内存
'''
self.db.commit()
self.cursor.close()
self.db.close()
class Student(Model):#model实例类的子类
name = StringField("name")
# print(name)
room_id = IntegerField("room_id")
# print(room_id)
u = Student(name = "张3",room_id = 6)#实质是创建了一个字典的对象
u.save()#调用父类的save方法
python自定义ORM并操作数据库的更多相关文章
- 使用python简单连接并操作数据库
python中连接并操作数据库 图示操作流程 一.使用的完整流程 # 1. 导入模块 from pymysql import connect # 2. 创建和数据库服务器的连接,自行设置 服务器地址, ...
- python如何用sqlalchemy操作数据库
工具:mysql python sqlalchemy ---------------------------------------- 准备工作: 1.安装mysql 如果是window环境请参考 ...
- python学习笔记:操作数据库
1.下载安装模块 第一种:cmd下:执行命令下载安装:pip3 install pymysql 第二种:IDE下pycharm python环境路径下添加模块 2.连接数据库 import pymys ...
- Python sqlalchemy orm 常用操作
增add # 创建表1 # 注:高级封装 import sqlalchemy # 调用链接数据库 from sqlalchemy import create_engine # 调用基类Base fro ...
- python测试开发django-13.操作数据库(增删改查)
前言 django的models模块里面可以新增一张表和字段,通常页面上的数据操作都来源于数据库的增删改查,django如何对msyql数据库增删改查操作呢? 本篇详细讲解django操作mysql数 ...
- Python学习笔记 - day11 - Python操作数据库
MySQL的事务 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关,MySQL的两种引擎如下: 1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID ...
- 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...
- Django中的ORM进阶操作
Django中的ORM进阶操作 Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互.但是仍然有几种操作是非常绕也特别容易混淆的.于是,针对这一块,来一个分类总结吧. ...
- 自定义ORM框架(转转)
ORM背景 在数据库界,主流的数据库都是关系型数据库,其采用的关系型数据结构模型,无论从数学上还是实践中都相当的成熟,得到非常广泛的应用.在关系型数据结构理 论中,所有的数据都组织成一个个相互独立的二 ...
随机推荐
- [转载] HashMap的工作原理-hashcode和equals的区别
目录 前言 为什么需要使用Hashcode,可以从Java集合的常用需求来描述: 更深入的介绍 先来些简单的问题 HashMap的0.75负载因子 总结 我在网上看到的这篇文章,介绍的很不错,但是我看 ...
- 原生JavaScript判断浏览器对CSS属性是否支持
/*判断浏览器是否支持某个css属性*/ function SupportCss(attrName){ var i=0, arr = SupportCss.opt.aBrowser, eleStyle ...
- docker之容器日志存储位置及把运行日志记录至文件
参考:https://www.cnblogs.com/YatHo/p/7866029.html docker启动后日志会在以下位置 /var/lib/docker/containers/容器ID/容器 ...
- python signal模块
signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时发出SIGALRM等.要注意,signal包主要是针对UNIX平台(比如Linux, MAC ...
- mysql 库、表、数据的增删改
数据库定义 语法形式 (1)创建数据库 create database [if not exists ] 数据库名 [charset 字符集] [collate 字符排序规则]; if not exi ...
- IP通信学习心得03
三.TCP.三次握手.四次挥手 1.TCP数据包结构 注: A:序列号字段是所发字节的第一个字节的序号. B:报头最大长度为60个字节(4bits),最小为20个字节. C: 发送窗口由接收窗口决定 ...
- 使用Docker-Compose编排发布.Net Core+Redis应用两个镜像到Docker
对于刚刚完成的Alipay支的Demo, 我想要把它部署到Docker中去, 下面我来演示相关步骤. 创建配置文件 配置文件的重中之重是Dockerfile, 他的内容如下: # 第一部分是编译并发布 ...
- Linux下go环境搭建
一:先从https://golang.google.cn/dl/下载,我这边下载的是go1.13.3.linux-amd64.tar.gz: 二:将压缩包解压后得到go目录,将go目录移动到/usr/ ...
- git config命令详解
Git有一个工具被称为git config,它允许你获得和设置配置变量:这些变量可以控制Git的外观和操作的各个方面. 一. 配置文件的存储位置 这些变量可以被存储在三个不同的位置: 1./etc/ ...
- 使用RestTemplate进行服务调用的几种方式
首先我们在名为MSG的服务中定义一个简单的方法 @RestController public class ServerController { @GetMapping("/msg" ...