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. Apache JMeter--1基础介绍

    一.JMeter 介绍 近期公司要做jmeter调研,将性能测试推广到全部测试组,便一边学习一边做记录. Apache JMeter是100%纯JAVA桌面应用程序,是一款优秀的开源性能测试工具,被设 ...

  2. Redis 安装及入门

    Redis简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. Docker方式安装Redis # 拉取 r ...

  3. 20. API概览 Schemas

    能被机器所理解的概要, 描述了通过api可得到的资源, URL, 表示方式以及支持的操作. API概要在很多使用场景下都是有用的工具, 例如生成参考文档, 或者驱动可以与API交互的动态客户端库. r ...

  4. Jekyll的_config文件配置报错

    8 April 2019 by IchiehPan Jekyll 搭建博客时, 修改完_config.yml文件后就收到了github的build error邮件. 大致内容如下: did not f ...

  5. Vue.observable()使用方法

    前言 随着组件的细化,就会遇到多组件状态共享的情况, Vuex当然可以解决这类问题,不过就像 Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是 vue.js ...

  6. Redis(1)——5种基本数据结构

    一.Redis 简介 "Redis is an open source (BSD licensed), in-memory data structure store, used as a d ...

  7. python fake_useragent模块 user-agent的获取

    1. UserAgent 模块使用 from fake_useragent import UserAgent ua = UserAgent() # 实例化,实例化时需要联网但是网站不太稳定 print ...

  8. Manjaro 19.01 kde下Tim sogou软件安装问题及解决

    我的系统配置 首先第一个问题是,在manjaro下Tim Thunderspeed这种deepin-wine的软件.今天我在装这些软件的时候,安装之后不能打开,闪退.苦恼了我好一会儿.终于找到了解决的 ...

  9. 一起了解 .Net Foundation 项目 No.11

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Microsoft Web ...

  10. 【30分钟学完】canvas动画|游戏基础(4):边界与碰撞

    前言 本系列前几篇中常出现物体跑到画布外的情况,本篇就是为了解决这个问题. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 越界检测 假定物体是个圆形,如图其圆心坐标即是物 ...