orm终极

  • 甩一个代码给你
# 创建字段

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 # varchar 字段类型
class StingField(Field):
def __init__(self, name, column_type='varchar(64)', 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) from day38.mysql_control import MySQL class OrmMetaClass(type):
def __new__(cls, class_name, class_bases, class_attr): # 将models的类名, 基类,以及类的名称空间传给自定义的元类
# 1、过滤掉除了我想控制的类以外的其他的类 此时是过滤掉models
if class_name == 'Models': # 将models类的类名,基类,类的名称空间原路返回
return type.__new__(cls, class_name, class_bases, class_attr) # 2、获取表名,若有自定义表名则用自定义表名,若没有则默认用类名做表名
table_name = class_attr.get('table_name', class_name) # 先将主键值设为None
primary_key = None # 想把字段名以及字段对象单独存放在一个字典中, 后面在把这个字典添加到类的 名称空间中去
mappings = {} # 3、保证一张表只能有唯一的一个主键
# 循环遍历获得字段 字段对象
for k, v in class_attr.items():
# print(k, v)
if isinstance(v, Field): # 4、将所有的 字段名 以及 字段对象 添加到一个独立的字典中
mappings[k] = v
# print(mappings) 查看mappings # 判断字段对象是否有主键,且主键是否唯一
if v.primary_key: # 若第二次进来,primary_key 有值,证明已经有一个主键了,抛出一个异常
if primary_key:
raise TypeError('一张表只能有一个主键') # 确定主键名
primary_key = v.name # 5、过滤掉类名称空间中与独立字典中重复的字段 已经字段属性
for key in mappings.keys():
class_attr.pop(key) if not primary_key:
raise TypeError('必须要有一个主键') # 6、再将表名 主键 独立的字典 添加到类的名称空间中去
class_attr['table_name'] = table_name
class_attr['primary_key'] = primary_key
class_attr['mappings'] = mappings # 7、返回给models类
return type.__new__(cls, class_name, class_bases, class_attr) class Models(dict, metaclass=OrmMetaClass): # 对象.属性 没有时 触发
def __getattr__(self, item): return self.get(item) # 将属性返回出去 比如将name返回出去 # 对象.属性 = 属性值 时触发
def __setattr__(self, key, value): # 给字典添加键值对的方式
self[key] = value # 查询数据
@classmethod
def select_data(cls, **kwargs): # **的作用是将传过来的打散
mysql_obj = MySQL() filed_value = None
# 若kwargs 为false代表没有查询条件
if not kwargs:
# 1、查所有
# sql = 'select * from 表名'
sql = f'select * from {cls.table_name}' else:
# 获取字段名
filed_name = list(kwargs.keys())[0] # 获取字段值
filed_value = kwargs.get(filed_name) # 2、根据条件查询
# select * from 表名 where 字段名 = 字段值;
sql = f'select * from {cls.table_name} where {filed_name}=?'
sql = sql.replace('?', '%s')
# print(filed_value) res = mysql_obj.select(sql, filed_value) return [cls(**i) for i in res] # ---> [{}, {}] --->[onj, obj] # 插入数据
def insert_data(self): # ---> user_obj
mysql_obj = MySQL() # sql :insert into 表名(字段名1, 字段名2) values(字段值1, 字段值2);
# 1、表名 ----> self.table_name
# 2、字段名与字段值 ---> mappings # 存放字段名的列表
filed_names = [] # [字段名, 字段名] # 存放字段值的列表
filed_values = [] # [字段值, 字段值] # 设置一个替换值的列表
replace_list = [] # [?, ?] for k, v in self.mappings.items(): # 获取字段名,追加到表中
filed_names.append(v.name) # 获取字段值,追加到列表中
filed_values.append(
# 反射:根据字符串操作对象中的属性或方法
self.get(v.name, v.default)
# getattr(self, v.name, v.default) 这个也可以,只是getattr 返回的是__getattr__返回的值。如果没有返回None
) replace_list.append('?') # sql = f'-- insert into {self.table_name}({",".join(filed_names)}) values({",".join(replace_list)})'
sql = 'insert into %s(%s) values(%s)' % (
self.table_name, ",".join(filed_names), ",".join(replace_list)
)
sql = sql.replace('?', '%s') mysql_obj.execute(sql, filed_values) # 更新数据
def update_data(self):
mysql_obj = MySQL() # sql :update 表名 set 字段名=字段名 where pk=主键值; # 主键值
pk = None # 存放字段名的列表
filed_name = [] # 存放字段值的列表
filed_values = [] for k, v in self.mappings.items():
# 判断mappings中那一个字段是主键
if v.primary_key:
# 获取主键的值
pk = getattr(self, v.name) else:
# 添加字段名
filed_name.append(v.name + '=?') # 添加字段值
filed_values.append(
getattr(self, v.name)
) #sql: update User set 字段名=字段值, 字段名=字段值
# sql: update User set username=?, password=? where pk=1; sql = 'update %s set %s where %s=%s' %(
self.table_name,
','.join(filed_name),
self.primary_key,
pk
) sql = sql.replace('?', '%s') mysql_obj.execute(sql, filed_values) class User(Models): id = IntegerField(name='id', primary_key=True)
username = StingField(name='username')
password = StingField(name='password') if __name__ == '__main__':
# user_obj = User(name='tank')
# print(user_obj)
# print(user_obj.name) # dict = {'name': 'tank'}
# print(type(dict.keys()))
# print(list(dict.keys())) # user_obj = User(username='JASON_DSB', password='123')
# user_obj.insert_data()
# 获取Jason对象
# user_obj = User.select_data(username='大didi')[0]
# # 修改对象中属性的值,然后再调用update方法更新到数据库中
# user_obj.username = '大jiji'
#
# user_obj.update_data()
user_obj = User.select_data()
print(user_obj)
  • mysql_pool.py
自定义一个mysql_pool.py文件
# pip install DBUtils
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='123456', #你们自己的密码是多少就写多少
database='orm_demo', # 换成你们自己想要连接的数据库
charset='utf8',
autocommit=True
)
  • mysql_control.py
自定义一个mysql_control.py
import pymysql
from mysql_pool import POOL # MySQL连接类
class MySQL: __instance = None # 单例模式
@classmethod
def singleton(cls):
if not cls.__instance:
cls.__instance = cls() return cls.__instance # 实例化MySQL类时,获取数据库链接对象,获取游标对象
def __init__(self):
# self.mysql_client = pymysql.connect()
self.mysql_client = POOL.connection() self.cursor = self.mysql_client.cursor(
pymysql.cursors.DictCursor
) # 自定义查询方法
def select(self, sql, args=None):
# 1、先提交查询sql语句
# select * from table;
# select * from table where id=%s;
self.cursor.execute(sql, args) # 2、获取返回的查询结果
# res ---> [{}, {}]
res = self.cursor.fetchall()
return res # 自定义提交sql语句方法,比如: insert、update
def execute(self, sql, args):
# 1、提交sql语句
# insert into table(字段) values(%s);
try:
self.cursor.execute(sql, args) except Exception as e:
print(e) def close(self):
# 先关闭游标
self.cursor.close()
# 再关闭数据库连接
self.mysql_client.close()

orm终极大爆炸的更多相关文章

  1. UWP中实现大爆炸效果(一)

    自从老罗搞出大爆炸之后,各家安卓都内置了类似功能.UWP怎么能落下呢,在这里我们就一起撸一个简单的大爆炸实现. 闲话不说,先上效果: 因为代码太多,所以我打算写成一个系列,下面是第一篇的正文: 首先, ...

  2. UWP中实现大爆炸效果(二)

    上一回实现了一个宽度不均匀的Panel,这次我们编写一个简单的BigbangView主体. 首先创建一个模板化控件,删掉Themes/Generic.xaml中的<Style TargetTyp ...

  3. UWP 大爆炸你个锤子

    今天看到  叫我蓝火火 s的 UWP中实现大爆炸效果(一) ,我也来说一下我的app [小薇自然语言处理]实现的大爆炸技术. 看一下效果先. 我的控件是基于wrappanel的,正如蓝火火说的,这样看 ...

  4. 数据大爆炸:KDD 2016

    2016"> 饕餮盛宴 ACM SIGKDD国际会议(简称KDD)是数据挖掘领域的顶级国际会议,由ACM (计算机协会)的数据挖掘及知识发现专委会(SIGKDD)负责组织筹办.在现今如 ...

  5. android上传位置信息导致的流量大爆炸问题调查

    原由:项目中有人写了个位置上传的服务,其实一直没问题,后来不知道什么时候出现了很多抱怨,是开着app流量一下子跑掉了几个G,差点就要卖房子还移动话费了,很多同事哭笑不得的找上门来,后来PM解决了,我一 ...

  6. Linux 大爆炸:一个内核,无数发行版

    即使你是一个 Linux 新人,你可能也已经知道它不是一个单一的.整体的操作系统,而是一群项目.这个星座中不同的“星”组成了“发行版”.每个都提供了自己的 Linux 模式. 感谢这一系列发行版所提供 ...

  7. 极客无极限 一行HTML5代码引发的创意大爆炸

    摘要:一行HTML5代码能做什么?国外开发者Jose Jesus Perez Aguinaga写了一行HTML5代码的文本编辑器.这件事在分享到Code Wall.Hacker News之后,引起了众 ...

  8. python从小白到大咖方便查看链接

    直通BAT面试题 PyCharm快捷键 一.python基础 01 python基础 02python中基本数据类型以及运算符 03流程控制之if,while,for 04基本数据类型内置方法一 05 ...

  9. 2016年AR行业十大热点事件汇总

    2016年即将接近尾声,增强现实在今年完成了里程碑式的跃进.无论是从新玩法的开发还是从大众接受度,以及行业巨头的青睐,无不证明这AR的无线潜力,故而,2016年算是AR的崛起之年. 纵观全年AR新闻事 ...

随机推荐

  1. Spring Data-Spring整合Hibernate基于JPA规范

    JPA:由 Sun 公司提供了一对对于持久层操作的标准(接口+文档) Hibernate:是 Gavin King 开发的一套对于持久层操作的自动的 ORM 框架. Hibernate JPA:是在 ...

  2. 2019 湖南多校第一场(2018~2019NCPC) 题解

    解题过程 开场shl过B,C,然后lfw写J,J WA了以后shl写A,但是因为OJ上空间开小WA了,而不是MLE?,J加了特判过了.之后一直在检查A错哪了,直到qt发现问题改了空间,浪费许多时间,但 ...

  3. Dijkstra(迪杰斯特拉求最短路径)-02-网络延迟时间

    有 N 个网络节点,标记为 1 到 N. 给定一个列表 times,表示信号经过有向边的传递时间. times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节 ...

  4. django学习02-模型的使用

    新手做的笔记,很可能会有理解错误的地方.欢迎拍砖. mysite/settings.py的INSTALLED_APPS选项中定义了几个默认的app,又如django.contrib.admin,dja ...

  5. flash存储器原理及作用是什么?

    flash存储器的工作原理 flash存储器又称闪存(快闪存储器),是一种电可擦可编程只读存储器的形式,是可以在操作中被多次擦或写,EEPROM与高速RAM成为当前最常用且发展最快的两种存储技术.计算 ...

  6. poj 2823 Sliding Windows (单调队列+输入输出挂)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426   Accepted: 20849 ...

  7. python基础实战之猜年龄游戏

    目录 一.Python基础实战之猜年龄游戏 给定年龄,用户可以猜三次年龄 年龄猜对,让用户选择两次奖励 用户选择两次奖励后可以退出 age = 18 # 答案 count = 0 # 游戏次数控制 p ...

  8. 牛客NOIP暑期七天营-提高组2

    第一题:ACGT 题目链接:https://ac.nowcoder.com/acm/contest/931/A trie树.hash.map遍历  ①.trie树上的节点多记一个rest值表示还有多少 ...

  9. WinForm GroupBox控件重绘外观

    private void groupBoxFun_Paint(PaintEventArgs e, GroupBox groupBox){ e.Graphics.Clear(groupBox.BackC ...

  10. C# 利用AForge进行摄像头信息采集

    概述 AForge.NET是一个专门为开发者和研究者基于C#框架设计的,提供了不同的类库和关于类库的资源,还有很多应用程序例子,包括计算机视觉与人工智能,图像处理,神经网络,遗传算法,机器学习,机器人 ...