准备知识

DBUtils模块  <<-----重点

DBUtils是Python的一个用于实现数据库连接池的模块

此连接池有两种连接模式:

    DBUtils提供两种外部接口:
PersistentDB :提供线程专用的数据库连接,并自动管理连接。
PooledDB :提供线程间可共享的数据库连接,并自动管理连接。
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=[], # 开始会话前执行的命令列表。
ping=0,
# ping MySQL服务端,检查是否服务可用。
host='127.0.0.1',
port=3306,
user='root',
password='',
database='youku',
charset='utf8',
autocommit = True
)

DBUtils,配置模板

def func():
...
conn = POOL.connection()
...

元类概念回顾(>>传送门点这里<<)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/05/17 8:25
# @Author : MJay_Lee
# @File : 列表推导式.py
# @Contact : limengjiejj@hotmail.com
egg_list = []
for i in range(10):
egg_list.append('egg%s' % i) print(egg_list)
# ['egg0', 'egg1', 'egg2', 'egg3', 'egg4', 'egg5', 'egg6', 'egg7', 'egg8', 'egg9'] egg_list2 = ['egg%s' % i for i in range(10)]
print(egg_list2)

列表推导式

class Foo:
x=1
def __init__(self,y):
self.y=y def __getattr__(self, item):
print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value):
print('----> from setattr')
# self.key=value #这就无限递归了,你好好想想
# self.__dict__[key]=value #应该使用它 def __delattr__(self, item):
print('----> from delattr')
# del self.item #无限递归了
self.__dict__.pop(item) #__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__) #__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx

__getattr__,__setattr__

补充:

class Foo:
def __init__(self,x):
self.x=x def __getattr__(self, item):
print('执行的是我')
# return self.__dict__[item]
def __getattribute__(self, item):
print('不管是否存在,我都会执行')
raise AttributeError('哈哈') f1=Foo(10)
f1.x
f1.xxxxxx #当__getattribute__与__getattr__同时存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError

区分__getattr__,__getattribute__

反射(update和save两个功能代码里,拼接SQL语句时,给参数赋值时时需要用上):

def getattr(object, name, default=None): # known special case of getattr
"""
getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
When a default argument is given, it is returned when the attribute doesn't
exist; without it, an exception is raised in that case.
"""
pass def setattr(x, y, v): # real signature unknown; restored from __doc__
"""
Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v''
"""
pass def delattr(x, y): # real signature unknown; restored from __doc__
"""
Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y''
"""
pass

getattr及其它相关属性

class BlackMedium:
feature='Ugly'
def __init__(self,name,addr):
self.name=name
self.addr=addr def sell_house(self):
print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name)
def rent_house(self):
print('%s 黑中介租房子啦,傻逼才租呢' %self.name) b1=BlackMedium('万成置地','回龙观天露园') #检测是否含有某属性
print(hasattr(b1,'name'))
print(hasattr(b1,'sell_house')) #获取属性
n=getattr(b1,'name')
print(n)
func=getattr(b1,'rent_house')
func() # getattr(b1,'aaaaaaaa') #报错
print(getattr(b1,'aaaaaaaa','不存在啊')) #设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1)) #删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
delattr(b1,'show_name111')#不存在,则报错 print(b1.__dict__)

类与对象的四个操作属性示例

操作类与对象的属性的补充:

class Foo:

    def __del__(self):
print('执行我啦') f1=Foo()
del f1
print('------->') #输出结果
执行我啦
-------> ----------------------以下是另一种情况
class Foo: def __del__(self):
print('执行我啦') f1=Foo()
# del f1
print('------->') #输出结果
------->
执行我啦 典型的应用场景: 创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中 当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

析构函数,__del__方法

format_dict={
'nat':'{obj.name}-{obj.addr}-{obj.type}',#学校名-学校地址-学校类型
'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
}
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type def __repr__(self):
return 'School(%s,%s)' %(self.name,self.addr)
def __str__(self):
return '(%s,%s)' %(self.name,self.addr) def __format__(self, format_spec):
# if format_spec
if not format_spec or format_spec not in format_dict:
format_spec='nat'
fmt=format_dict[format_spec]
return fmt.format(obj=self) s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1) '''
str函数或者print函数--->obj.__str__()
repr或者交互式解释器--->obj.__repr__()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常
'''
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))

自定义打印格式,__str__方法

单例 (>>传送门点这里<<)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/04/18 17:47
# @Author : MJay_Lee
# @File : 单例.py
# @Contact : limengjiejj@hotmail.com # 基于元类实现单例模式
# 单例:即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省空间(场景:假若从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了) # 方式一:定义一个类方法实现单例模式
# import setting
#
# class Mysql:
# instance = None
# def __init__(self,host,port):
# self.host = host
# self.port = port
#
# @classmethod
# def from_conf(self):
# if not Mysql.instance:
# res = Mysql(setting.HOST, setting.PORT)
# Mysql.instance = res
# return Mysql.instance
#
# # con1 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7FC7978>
# # con2 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7FD8710>
# # con3 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x000000A9F7E09C88>
# # print(con1,con2,con3)
# #
#
# # con1 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4DD8>
# # con2 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4E48>
# # con3 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BB72BA4E80>
# # print(con1,con2,con3)
#
# con1 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
# con2 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
# con3 = Mysql.from_conf() # <__main__.Mysql object at 0x000000BD5BBA4DD8>
# print(con1 is con2 is con3) # True # # 方式二:定制元类实现
# # 若从配置文件取相同配置产生对象则实现单例,若传值则新建对象
import setting class Mymeta(type):
def __init__(self,name,bases,dic): # 定义类Mysql时就触发 # 事先从配置文件中取配置来造一个Mysql的实例出来
self.__instance = object.__new__(self) # 产生对象
self.__init__(self.__instance,setting.HOST,setting.PORT) # 初始化对象
#上述两步可合并下面一步
# self.__instance = super().__call__(*args,**kwargs) super().__init__(name,bases,dic) def __call__(self, *args, **kwargs): # Mysql(...)时触发
if args or kwargs: # Mymeta类的对象括号内传值则新建obj,否则返回self.__instance
obj = object.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
return self.__instance # Mysql = Mymeta('Mysql',(obj,),class_dic)
class Mysql(metaclass=Mymeta):
def __init__(self,host,port):
self.host = host
self.port = port con1 = Mysql()
con2 = Mysql()
# con3 = Mysql() # <__main__.Mysql object at 0x0000008BA7E24DD8>
# con4 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x0000004B4B904EF0>,若Mymeta类的对象(Mysql)括号内传值则新建obj
# print(con4) # True # 装饰器实现单例
# import setting
#
# def single_obj(cls):
# __instance = cls(setting.HOST,setting.PORT)
# def wrapper(*args, **kwargs):
# if args or kwargs:
# obj = cls(*args, **kwargs)
# return obj
# return __instance
# return wrapper
#
# @single_obj
# class Mysql:
# def __init__(self,host,port):
# self.host = host
# self.port = port
#
# con1 = Mysql() # <__main__.Mysql object at 0x0000001F978D9C88>
# con2 = Mysql() # <__main__.Mysql object at 0x0000001F978D9C88>
# con3 = Mysql('127.0.0.1',80) # <__main__.Mysql object at 0x0000001F98AE4DD8>
#
# print(con1 is con2) # True

三个方法实现单例--示例


ORM简介

ORM即Object Relational Mapping,全称对象关系映射
当我们需要对数据库进行操作时,势必需要通过连接数据、调用sql语句、执行sql语句等操作,ORM将数据库中的表,字段,行与我们面向对象编程的类及其方法,属性等一一对应,即将该部分操作封装起来,程序猿不需懂得sql语句即可完成对数据库的操作。

一、知识储备:

1、在实例化一个user对象的时候,可以user=User(name='lqz',password='123')

2 也可以 user=User()

    user['name']='lqz'
    user['password']='123'
3 也可以 user=User()

    user.name='lqz'
    user.password='password'

前两种,可以通过继承字典dict来实现,第三种,用getattr和setattr:

__getattr__ 拦截点号运算。当对未定义的属性名称和实例进行点号运算时,就会用属性名作为字符串调用这个方法。如果继承树可以找到该属性,则不调用此方法

__setattr__会拦截所有属性的的赋值语句。如果定义了这个方法,self.arrt = value 就会变成self,__setattr__("attr", value).这个需要注意。当在__setattr__方法内对属性进行赋值是,不可使用self.attr = value,因为他会再次调用self,__setattr__("attr", value),则会形成无穷递归循环,最后导致堆栈溢出异常。应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name'] = value

 二、定义Model基类

# 在ModelsMetaclass中自定义拦截实例化对象的方法
class Models(dict,metaclass=ModelsMetaclass):
# k,v形式的值
def __init__(self,**kwargs):
super().__init__(**kwargs) # 写存
def __setattr__(self, key, value):
self[key] = value # 读取
def __getattr__(self, item):
try:
return self[item]
except KeyError:
raise ('没有该属性')

三、定义Field

数据库中每一列数据,都有:列名,列的数据类型,是否是主键,默认值

# 表示一个列:列名,列的类型,列的主键和默认值
class Field:
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 class StringField(Field):
def __init__(self,name=None,column_type='varchar(200)',primary_key=False,default=None):
super().__init__(name,column_type,primary_key,default) class IntegerField(Field):
def __init__(self,name=None,column_type='int',primary_key=False,default=None):
super().__init__(name,column_type,primary_key,default)

四、定义元类

数据库中的每个表,都有表名,每一列的列名,以及主键是哪一列

既然我要用数据库中的表,对应这一个程序中的类,那么我这个类也应该有这些类属性

但是不同的类这些类属性又不尽相同,所以我应该怎么做?在元类里拦截类的创建过程,然后把这些东西取出来,放到类里面

class ModelsMetaclass(type):
def __new__(cls,name,bases,attrs): if name == 'Models': #
return type.__new__(cls, name, bases, attrs)
table_name = attrs.get('table_name', None) #字典取值,中括号或.get
if not table_name:
table_name = name primary_key = None
mappings = dict()
for k, v in attrs.items():
if isinstance(v, Field): # v 是不是Field的对象
mappings[k] = v
if v.primary_key: # v是基类对象,即判断该字段的主键 # 找到主键
if primary_key:
raise TypeError('主键重复:%s' % k)
primary_key = k for k in mappings.keys():
attrs.pop(k) # 执行完此步后,attrs中只剩余有__属性__
if not primary_key:
raise TypeError('没有主键')
attrs['table_name'] = table_name
attrs['primary_key'] = primary_key
attrs['mappings'] = mappings
return type.__new__(cls, name, bases, attrs)

五、基于pymysql的数据库操作类(单例)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/05/15 10:44
# @Author : MJay_Lee
# @File : mysql_singleton.py
# @Contact : limengjiejj@hotmail.com import pymysql class Mysql_interface:
__instense = None
def __init__(self):
self.conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
charset = 'utf8',
database = 'youku',
autocommit = True
)
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) def close_db(self):
self.cursor.close()
self.conn.close() def select(self,sql,args):
self.cursor.execute(sql,args)
re = self.cursor.fetchall() return re def execute(self,sql,args):
try:
self.cursor.execute(sql,args)
affected = self.cursor.rowcount
except BaseException as e:
print(e)
return affected @classmethod
def singleton(cls):
if not cls.__instense:
cls.__instense = cls()
return cls.__instense if __name__ == '__main__':
ms = Mysql_interface()
re = ms.select('select * from user where id = %s',1)
print(re)

六、继续Models基类

Models类是所有要对应数据库表类的基类,所以,Models的元类应该是咱们上面写的那个

而每个数据库表对应类的对象,都应该有查询、插入、保存,方法

所以:

# 在ModelsMetaclass中自定义拦截实例化对象的方法
class Models(dict,metaclass=ModelsMetaclass):
# k,v形式的值
def __init__(self,**kwargs):
super().__init__(**kwargs) # 写存
def __setattr__(self, key, value):
self[key] = value # 读取
def __getattr__(self, item):
try:
return self[item]
except KeyError:
raise ('没有该属性') @classmethod
def select_one(cls,**kwargs):
'''
查一条
:param kwargs:
:return:
'''
key = list(kwargs.keys())[0]
value = kwargs[key] # select * from user where id=%s
sql = 'select * from %s where %s =?' % (cls.table_name,key)
sql = sql.replace('?','%s')
ms = mysql_singleton.Mysql_interface().singleton()
re = ms.select(sql,value) # 得到re字典对象
if re:
# attrs = {'name':'lmj','password':123}
# User(**attrs)
# 相当于 User(name='lmj',password=123)
return cls(**re[0])
else:
return @classmethod
def select_many(cls, **kwargs):
'''
查多条
:param kwargs:
:return:
'''
ms = mysql_singleton.Mysql_interface().singleton()
if kwargs:
key = list(kwargs.keys())[0]
value = kwargs[key] sql = 'select * from %s where %s =?' % (cls.table_name, key)
sql = sql.replace('?', '%s')
re = ms.select(sql, value) # 得到re字典对象
else:
sql = 'select * from %s' % (cls.table_name)
re = ms.select(sql)
if re:
obj_list = [cls(**r) for r in re]
return obj_list
else:
return def update(self):
ms = mysql_singleton.Mysql_interface().singleton()
# update user set name = ?,password = ? where id = ? filed_data = [] # name = ?,password = ?
pr = None
args = [] # 字段的值
for k,v in self.mappings.items():
if v.primary_key:
pr = getattr(self,v.name,v.default)
else:
filed_data.append(v.name + '=?')
args.append(getattr(self,v.name,v.default)) sql = 'update %s set %s where %s = %s' % (self.table_name,','.join(filed_data),self.primary_key,pr)
sql = sql.replace('?','%s')
ms.execute(sql,args) def save(self):
ms = mysql_singleton.Mysql_interface().singleton()
# insert into user(name,password) values (?,?)
field_data = []
args = []
value_data = []
for k,v in self.mappings.items():
if not v.primary_key:
field_data.append(v.name)
args.append(getattr(self,v.name,v.default))
value_data.append('?') sql = 'insert into %s(%s) VALUES (%s)' % (self.table_name,','.join(field_data),','.join(value_data))
sql = sql.replace('?','%s')
ms.execute(sql,args)

数据库池版,orm_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=[], # 开始会话前执行的命令列表。
ping=0,
# ping MySQL服务端,检查是否服务可用。
host='127.0.0.1',
port=3306,
user='root',
password='',
database='youku',
charset='utf8',
autocommit = True
) def func():
# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
# 否则
# 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
conn = POOL.connection() # print('链接被拿走了', conn._con)
# print('池子里目前有', POOL._idle_cache, '\r\n') cursor = conn.cursor()
cursor.execute('select * from user')
result = cursor.fetchall()
print(result)
conn.close() if __name__ == '__main__': func()

orm_pool.py

mysql_pool的配置:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/05/15 10:44
# @Author : MJay_Lee
# @File : mysql_pool.py
# @Contact : limengjiejj@hotmail.com from video_web_mysql.orm_pool import orm_pool
import pymysql class Mysql_interface:
def __init__(self):
self.conn = orm_pool.POOL.connection()
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) def close_db(self):
self.cursor.close()
self.conn.close() def select(self,sql,args=None):
self.cursor.execute(sql,args)
re = self.cursor.fetchall() return re def execute(self,sql,args):
try:
self.cursor.execute(sql,args)
affected = self.cursor.rowcount
except BaseException as e:
print(e)
return affected if __name__ == '__main__':
ms = Mysql_interface()
re = ms.select('select * from user where id = %s',1)
print(re)

mysql_pool.py

fuckorm的完整源码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/05/15 8:58
# @Author : MJay_Lee
# @File : fuckorm.py
# @Contact : limengjiejj@hotmail.com from video_web_mysql.orm_pool import mysql_pool # 表示一个列:列名,列的类型,列的主键和默认值
class Field:
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 class StringField(Field):
def __init__(self,name=None,column_type='varchar(200)',primary_key=False,default=None):
super().__init__(name,column_type,primary_key,default) class IntegerField(Field):
def __init__(self,name=None,column_type='int',primary_key=False,default=None):
super().__init__(name,column_type,primary_key,default) class ModelsMetaclass(type):
def __new__(cls,name,bases,attrs): if name == 'Models': #
return type.__new__(cls, name, bases, attrs)
table_name = attrs.get('table_name', None) #字典取值,中括号或.get
if not table_name:
table_name = name primary_key = None
mappings = dict()
for k, v in attrs.items():
if isinstance(v, Field): # v 是不是Field的对象
mappings[k] = v
if v.primary_key: # v是基类对象,即判断该字段的主键 # 找到主键
if primary_key:
raise TypeError('主键重复:%s' % k)
primary_key = k for k in mappings.keys():
attrs.pop(k) # 执行完此步后,attrs中只剩余有__属性__
if not primary_key:
raise TypeError('没有主键')
attrs['table_name'] = table_name
attrs['primary_key'] = primary_key
attrs['mappings'] = mappings
return type.__new__(cls, name, bases, attrs) # 在ModelsMetaclass中自定义拦截实例化对象的方法
class Models(dict,metaclass=ModelsMetaclass):
# k,v形式的值
def __init__(self,**kwargs):
super().__init__(**kwargs) # 写存
def __setattr__(self, key, value):
self[key] = value # 读取
def __getattr__(self, item):
try:
return self[item]
except KeyError:
raise ('没有该属性') @classmethod
def select_one(cls,**kwargs):
'''
查一条
:param kwargs:
:return:
'''
key = list(kwargs.keys())[0]
value = kwargs[key] # select * from user where id=%s
sql = 'select * from %s where %s =?' % (cls.table_name,key)
sql = sql.replace('?','%s')
ms = mysql_pool.Mysql_interface()
re = ms.select(sql,value) # 得到re字典对象
if re:
# attrs = {'name':'lmj','password':123}
# User(**attrs)
# 相当于 User(name='lmj',password=123)
return cls(**re[0])
else:
return @classmethod
def select_many(cls, **kwargs):
'''
查多条
:param kwargs:
:return:
'''
ms = mysql_pool.Mysql_interface()
if kwargs:
key = list(kwargs.keys())[0]
value = kwargs[key] sql = 'select * from %s where %s =?' % (cls.table_name, key)
sql = sql.replace('?', '%s')
re = ms.select(sql, value) # 得到re字典对象
else:
sql = 'select * from %s' % (cls.table_name)
re = ms.select(sql)
if re:
obj_list = [cls(**r) for r in re]
return obj_list
else:
return def update(self):
ms = mysql_pool.Mysql_interface()
# update user set name = ?,password = ? where id = ? filed_data = [] # name = ?,password = ?
pr = None
args = [] # 字段的值
for k,v in self.mappings.items():
if v.primary_key:
pr = getattr(self,v.name,v.default)
else:
filed_data.append(v.name + '=?')
args.append(getattr(self,v.name,v.default)) sql = 'update %s set %s where %s = %s' % (self.table_name,','.join(filed_data),self.primary_key,pr)
sql = sql.replace('?','%s')
ms.execute(sql,args) def save(self):
ms = mysql_pool.Mysql_interface()
# insert into user(name,password) values (?,?)
field_data = []
args = []
value_data = []
for k,v in self.mappings.items():
# 此处判断是否为自增主键,否则插入时避免还需手动输入主键ID
if not v.primary_key:
field_data.append(v.name)
value_data.append('?')
args.append(getattr(self, v.name, v.default)) sql = 'insert into %s(%s) VALUES (%s)' % (self.table_name,','.join(field_data),','.join(value_data))
sql = sql.replace('?','%s')
ms.execute(sql,args) class User(Models):
'''
首先赋值表名
其次根据数据库表结构来赋值
'''
table_name = 'user'
# k v(Field的对象)
id = IntegerField('id',primary_key=True)
password = StringField('password') class Notice(Models):
table_name = 'notice'
id = IntegerField('id',primary_key=True)
name = StringField('name')
content = StringField('content')
user_id = IntegerField('user_id') if __name__ == '__main__':
# notice = Notice.select_one(id=1)
# print(notice.content) # notice_list = Notice.select_many(id=1)
# print(notice_list) # notice.name = '改变了'
# notice.update() notice = Notice(name='',content='新插入',user_id=1)
notice.save()

fuckorm.py

增删改查,基础功能均亲测有效。

自己动手写一个简易对象关系映射,ORM(单例版和数据库池版)的更多相关文章

  1. 对象关系映射ORM

    对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效 ...

  2. Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包

    Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...

  3. Django 源码小剖: Django 对象关系映射(ORM)

    引 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django O ...

  4. Python 3 对象关系映射(ORM)

    ORM 对象关系映射 Object Relational Mapping 表 ---> 类 字段 ---> 属性 记录 ---> 对象 # mysql_client.py impor ...

  5. 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

    通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...

  6. 对象关系映射 ORM

    1.1 作用 MTV框架中包括一个重要的部分,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因 ...

  7. 对象关系映射(ORM)框架GreenDao简介和基本使用

    官网上的介绍,greenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案. GreenDao特点 性能最大化,可能是Android平台上最快的ORM框架 易于使用的A ...

  8. 对象-关系映射ORM(Object Relational Mapping)(转)

    ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现 Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件 ...

  9. 解析大型.NET ERP系统数据访问 对象关系映射框架LLBL Gen Pro

    LLBL Gen Pro是一个为.NET开发人员设计的的对象关系映射(ORM)框架,与NHibernate,Entity Framework等框架一样,通过实体与数据表的映射,实现关系数据库持久化. ...

随机推荐

  1. 颤振错误:当前Flutter SDK版本为2.1.0-dev.0.0.flutter-be6309690f?

    我刚刚升级了我的扑动,升级后我无法在Android Studio上运行任何扑动项目.我收到此错误消息. The current Dart SDK version -dev.0.0.flutter-be ...

  2. Oracle 计算两个日期间隔的天数、月数和年数

    在Oracle中计算两个日期间隔的天数.月数和年数: 一.天数: 在Oracle中,两个日期直接相减,便可以得到天数: select to_date('08/06/2015','mm/dd/yyyy' ...

  3. 常用cmd命令大全

    最早的电脑系统是从DOS系统开始,DOS时代没有现在Windows这样的视窗操作界面,让你输入命令.随着电脑的发展至今,学习一些常用cmd命令大全是很有必要.大多数的程序员高手们或计算机专家在DOS系 ...

  4. MySQL复制报错(Slave failed to initialize relay log info structure from the repository)

    机器重启以后,主从出现了问题,具体报错信息: Slave failed to initialize relay log info structure from the repository 解决方案: ...

  5. 自动化测试基础篇--Selenium unittest简介

    一.什么是unittest unittest是Python单元测试框架,类似于JUnit框架. unittest中有4个重要的概念:test fixture, test case, test suit ...

  6. Hive开窗函数的理解

    1.从一个sql语句开始 select id,sum(price) over(partition by id order by price desc) from books; sum作为聚合函数的时候 ...

  7. Spring注解开发-全面解析常用注解使用方法之生命周期

    本文github位置:https://github.com/WillVi/Spring-Annotation/ 往期文章:Spring注解开发-全面解析常用注解使用方法之组件注册 bean生命周期 ​ ...

  8. web安全职位面试题目汇总

    Domain 解释一下同源策略 同源策略,那些东西是同源可以获取到的 如果子域名和顶级域名不同源,在哪里可以设置叫他们同源 如何设置可以跨域请求数据?jsonp是做什么的? Ajax Ajax是否遵循 ...

  9. codeforces 633E Startup Funding(浮点数处理)

    codeforces 633E Startup Funding 题意 枚举左端点,对于每个左端点求一个最大的右端点使得最大. 对于得到的这个数组,随机选择k个数,求最小值期望. 题解 对于每个左端点, ...

  10. Java.util 包(Date 类、Calendar类、Random类)

    java.util 包提供了一些实用的方法和数据结构. Date 类 Date 类表示日期和时间,里面封装了操作日期和时间的方法.Date 类经常用来获取系统当前时间. 构造方法: 构造方法 说明 D ...