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. 修改xampp中phpmyadmin用户管理

    用相关软件打开位于D:/xampp/phpMyAdmin文件夹中的config.inc.php文件. 搜索$cfg['Servers'][$i]['auth_type'] = 'config'; 将其 ...

  2. Git的安装与TortoiseGit的安装和汉化

    下载Git 进入https://git-scm.com/downloads 可以看到如下界面 因为我是windows系统,选择windows即可. 有的朋友因为网络慢的一些原因不能很快下载下来,可以进 ...

  3. 程序小白如何快速开发OA办公系统

    对于企业开发oa办公系统,成本高,周期长.有些企业花高价购买,购买后受制于软件商,很多功能只能按原来设计需求走,无法升级或者升级慢.这些由于软件商的开发效率低难以及时地响应企业的需求变化,所以就有可能 ...

  4. sql -- 多表关联,update(用户奖励)

    表设计: users_buy: users_score: 需求: 1.根据用户分组,找出用户消费最高的金额 select user_name, max(paymoney) as pm from use ...

  5. 吐槽苹果开放接口のappleid登陆

    这里吐槽一下苹果的开发文档,一切源于前段时间,公司的产品app(某知名资讯app)要接入苹果登陆(ios13发布以来,apple就流氓要求新上线的app,如果有第三方登陆的话,必须要接入appleid ...

  6. AI:深度学习用于文本处理

    同本文一起发布的另外一篇文章中,提到了 BlueDot 公司,这个公司致力于利用人工智能保护全球人民免受传染病的侵害,在本次疫情还没有引起强烈关注时,就提前一周发出预警,一周的时间,多么宝贵! 他们的 ...

  7. 简单说 JavaScript中的tostring( ) 与 valueOf( )方法

    说明 所有的对象都继承有toString() 和 valueOf() 方法,对象到字符串,对象到数字的转换,会通过调用待转换对象的这两个方法中的一个来完成. 解释 toString( )方法的作用是: ...

  8. HTML5中form的新增属性或元素

    1.新增的表单元素 1.1 progress表示任务的完成情况,常用于进度条. max 定义进度元素所要求的任务的工作量,默认值为1 value 定义已经完成的工作量,如果max值为1,该值必须是介于 ...

  9. LeetCode37 使用回溯算法实现解数独,详解剪枝优化

    本文始发于个人公众号:TechFlow,原创不易,求个关注 数独是一个老少咸宜的益智游戏,一直有很多拥趸.但是有没有想过,数独游戏是怎么创造出来的呢?当然我们可以每一关都人工设置,但是显然这工作量非常 ...

  10. 怎么查看linux文件夹下有多少个文件(mac同样)

    查看目录下有多少个文件及文件夹,在终端输入 ls | wc -w 查看目录下有多少个文件,在终端输入 ls | wc -c 查看文件夹下有多少个文件,多少个子目录,在终端输入 ls -l |wc -l ...