u库

ORM:对象关系映射
类 》》》 数据库的一张表
对象 》》》 表的一条记录
对象点属性 》》》 记录某一个字段对应的值
'''
对象就是一个容器,里面装着属性和方法,而类就是盛放对象的一堆属性和方法,对象点来获取属性和方法。表就是装着一堆记录数据,通过对象点属性去获取某一个字段对应的值
'''
'''
一个字段有字段名,字段类型,字段是否是主键,字段的默认值,通过类返回的对象去点这些属性
'''
the first step:
先将表中的字段的各个属性字段名,字段类型,字段是否是主键,字段的默认值存放在类中,对象可以通过点来获取到某一个字段对应的值 the second step:
针对字段类型来写类,字段类型就有字符串类型(varchar,char),int
先写一个可以定义varchar类型字段的类,再写定义一个整型字段的类 the thrid step:
定义三个类User,Notice,Movie,这三个类不能写__init__,用父类来写一个__init__,在实列化对象的时候,不管传多少个关键字实参我都可以满足,不同的对象传入的关键字实参不等,但都可以实例化被同一个父类实例化出来,能想到的是字典的实例化d=dict(),父类中就继承这个字典这个类就可以实现 the fourth step:
d=dict(name='json',password='123')
name='json',password='123'这些都是对象属性对应的值,并不是对象的属性,所以d.name就是报错,(dict.get('name')这是字典的取值方式)
'''
有双杆的都表示自动触发
'''
__getattr__:在对象获取它没有的属性和方法的时候自动触发
__setattr__:在对象点属性设置属性值的时候自动触发
getattr():根据字符串获取对象对应属性和方法
所以要在父类中加入def __getattr__和__setattr__来获取数据和修改数据 the fifth step:
一张表要有表名,一个主键,好多字段,说明这个类里面有表名,有字段,有主键,元类就是用来创建类,而现在的类就是对应的一张表,所以创建类就是创建表,在类创建之前就哟啊拦截这个类,将这些塞给这个类,才算是一张表
user,notice,movie三个类是就是三个表,三个表都是继承models,所以models中继承元类。
'''
当类名为models时,就不需要拦截,原本该怎么创建就怎么创建,因为models并不是一张表,只是在创表的那个类继承models的方法,也就是用到字典类传参的那个功能而定义的类,之所以要models继承这个元类是因为是所有表类继承的父类,为了图方便就直接继承
'''
'''
元类中的__new__就是造一个名称空间,为了拦截的是创建表格的创建,创建的空间需要类名和基类和类体。
'''
'''
创建user这个类的时候,右键运行,会先跳到元类中,而user类中的代码也就是元类中class_attrs中的属性代码,所以元类中的class_attrs中已包含user中的代码还有自己为class_attrs这个字典自加的代码
'''

orm.py

from mysql_singlenton 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,默认主键为False,默认值为None
class StringField(Field):
def __init__(self, name, column_type='varchar(32)', primary_key=False, default=None):
# 调用父类的__init__
super().__init__(name, column_type, primary_key, default) # 定义一个整型字段的类
class IntegerField(Field):
def __init__(self, name, column_type='int', primary_key=False, default=None):
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)
# 获取类体代码中的属性,如果没有表名,就用类名来作为表名
# 注意:get获取key,返回vaule,如果没有就返回None,如果写了第二个参数就返回第二个参数
table_name = class_attrs.get('table_name', class_name)
primary_key = None
# 只要是表的字段的,我都放在字典中去,就不需要一个个去拿,直接拿到一个字典就有所有的字段了
mappings = {}
for k, v in class_attrs.items():
# 拿出所有自己定义的表属性,过滤掉那个table_name
# v是对象,Field是类,判断这个对象是否属于这个类
if isinstance(v, Field):
mappings[k] = v
if v.primary_key:
# 以防创建两个主键
if primary_key:
raise TypeError('一张表只能有一个主键')
primary_key = k
for k in mappings.keys():
# 将单个的字段删除,for循环mappings拿到所有的字段
class_attrs.pop(k)
# 创建一个表有且要有一个主键,如果没有这个主键,那么就要报错
if not primary_key:
raise TypeError('一张表必须要有主键') # 以下是将所有在名称空间中的属性数据都保存起来,调用父类的__new__进行保存到名称空间中
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) # self是字典的对象,
def __getattr__(self, item):
self.get(item, '没有该键') # 在没有这个item这个值的时候才会触发后面的‘没有该键’ def __setattr__(self, key, value):
try:
self[key] = value
except BaseException as e:
print(e) @classmethod
def select(cls, **kwargs):
# 调用Mysql的查询方法
ms = Mysql.singleton()
# select * from %s
# 当没有参数传入,代表查询所有的数据
if not kwargs:
sql = 'select * from %s' % cls.table_name
res = ms.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 = ms.select(sql, v)
if res:
print(res)
return [cls(**r) for r in res]
# select * from %s where %s=%s if __name__ == '__main__':
class User(Models):
table_name = 'userinfo'
id = IntegerField(name='id', primary_key=True)
name = StringField(name='name') rs = User.select(password='123')
print(rs) class Notice(Models):
pass class Movie(Models):
pass

mysql_singlenton.py

import pymysql

class Mysql(object):
_instance = None
def __init__(self):
self.conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123',
database='day41',
charset='utf8',
autocommit=True
)
self.cursor = self.conn.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)
# 注意一点:fetchall拿到的数据结构是一个列表套字典[{},{},{}]
res = self.cursor.fetchall()
return res def execute(self, sql,args):
#insert into user(name,password) values('jason','123')
#update user set name='jason',password='456' where id=1
try:
self.cursor.execute(sql,args)
except BaseException as e:
print(e) @classmethod
def singleton(cls):
if not cls._instance:
cls._instance = cls()
return cls._instance

u库前戏的更多相关文章

  1. 1.Python3标准库--前戏

    Python有一个很大的优势便是在于其拥有丰富的第三方库,可以解决很多很多问题.其实Python的标准库也是非常丰富的,今后我将介绍一下Python的标准库. 这个教程使用的书籍就叫做<Pyth ...

  2. C 构造一个 简单配置文件读取库

    前言 最近看到这篇文章, json引擎性能对比报告 http://www.oschina.net/news/61942/cpp-json-compare?utm_source=tuicool 感觉技术 ...

  3. C 封装一个简单二叉树基库

    引文 今天分享一个喜欢佩服的伟人,应该算人类文明极大突破者.收藏过一张纸币类型如下 那我们继续科普一段关于他的简介 '高斯有些孤傲,但令人惊奇的是,他春风得意地度过了中产阶级的一生,而  没有遭受到冷 ...

  4. 实现一个javascript手势库 -- base-gesture.js

    现在移动端这么普及呢,我们在手机上可以操作更多了.对于网页来说实现一些丰富的操作感觉也是非常有必要的,对吧(如果你仅仅需要click,,那就当我没说咯...)~~比如实现上下,左右滑动,点击之类的,加 ...

  5. 人工智能(AI)库TensorFlow 踩坑日记之一

    上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...

  6. python 全栈开发,Day60(MySQL的前戏,数据库概述,MySQL安装和基本管理,初识MySQL语句)

    一.MySQL的前戏 在学习Mysql之前,我们先来想一下一开始做的登录注册案例,当时我们把用户的信息保存到一个文件中: #用户名 |密码 root|123321 alex|123123 上面文件内容 ...

  7. linux动态库编译和使用详细剖析 - 后续

    引言 - 也许是修行 很久以前写过关于动态库科普文章, 废话反正是说了好多. 核心就是在 linux 上面玩了一下 dlopen : ) linux动态库编译和使用详细剖析 - https://www ...

  8. C高级 跨平台协程库

    1.0 协程库引言 协程对于上层语言还是比较常见的. 例如C# 中 yield retrun, lua 中 coroutine.yield 等来构建同步并发的程序. 本文就是探讨如何从底层实现开发级别 ...

  9. C基础 多用户分级日志库 sclog

    引言 - sclog 总的设计思路 sclog在之前已经内置到simplec 简易c开发框架中一个日志库. 最近对其重新设计了一下. 减少了对外暴露的接口. 也是C开发中一个轮子. 比较简单, 非常适 ...

随机推荐

  1. 深入理解Tomcat(12)拾遗

    前言 如何使用? 源码解读 总结 前言 Tomcat为了提高性能,在接受到socket传入的字节之后并不会马上进行编码转换,而是保持byte[]的方式,在用到的时候再进行转换.在tomcat的实现中, ...

  2. 泰拉瑞亚Linux主机打造指南

    最近玩了泰拉瑞亚,一个2D版的我的世界,但苦于steam的联机太过不靠谱,经常会出现和朋友之间联机失败的问题,所以我把服务器放到了部署我博客的服务器,这样就可以通过IP直接让好友加入游戏了! 首先是购 ...

  3. 线程中断 interrupt 和 LockSupport

    本文章将要介绍的内容有以下几点,读者朋友也可先自行思考一下相关问题: 线程中断 interrupt 方法怎么理解,意思就是线程中断了吗?那当前线程还能继续执行吗? 判断线程是否中断的方法有几个,它们之 ...

  4. nginx 命令行参数 启动 重启 重载 停止

    今天和大家分享关于 nginx 的一些参数使用 首先,你应该安装了nginx CentOS 安装 nginx 这是很早之前的一篇博客,可以参考. 之前,我们如何去操作 nginx ##简单粗暴法 pk ...

  5. 达拉草201771010105《面向对象程序设计(java)》第十二周学习总结

    达拉草201771010105<面向对象程序设计(java)>第十二周学习总结 第一部分:理论知识 Java的抽象窗口工具箱(AbstractWindow Toolkit,AWT)包含在j ...

  6. 从0到1,本地到远程git程序过程

    从0到1,本地到远程git程序过程 切记一定要在需要提交代码的文件夹下git init,既是你使用了什么 tortoisegit什么工具,或者你在idea环境下已经add了,但是仍然需要你在当前文件夹 ...

  7. Ubuntu18.04下安装mysql5.7超详细步骤

    1.首先执行下面三条命令: #安装mysql服务 sudo apt-get install mysql-server #安装客户端 sudo apt install mysql-client #安装依 ...

  8. mongoDb性能提升

    最近在弄MongoDB的时候 发现只按照官网的方式进行操作的话,性能不行,想着用单例模式封装一下,提升一下性能,代码如下: //引入mongodb相关的模块 const MongoClient = r ...

  9. c语言之单向链表

    0x00 什么是链表 链表可以说是一种最为基础的数据结构了,而单向链表更是基础中的基础.链表是由一组元素以特定的顺序组合或链接在一起的,不同元素之间在逻辑上相邻,但是在物理上并不一定相邻.在维护一组数 ...

  10. Java并发ReentrantLock

    ReentrantLock简介 可重入锁,作用是使线程安全.对比于sychronized,它能具有以下特点 减小资源锁的力度 更可控,减少发生死锁的概率 加锁.释放锁都是显示控制的 添加锁的作用时间来 ...