zoukankan      html  css  js  c++  java
  • orm 1. 数据库池orm 2.单例orm

    今日内容
    orm

    1. 数据库池orm  

    2.单例orm

    1. 数据库池orm  

    文件夹:orm_pool

    文件:db_pool.py

     1 from DBUtils.PooledDB import PooledDB
     2 import pymysql
     3 
     4 POOL = PooledDB(
     5     creator=pymysql,  # 使用链接数据库的模块
     6     maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
     7     mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
     8     maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
     9     maxshared=3,
    10     # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    11     blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    12     maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    13     setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    14     ping=0,
    15     # 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
    16     host='127.0.0.1',
    17     port=3306,
    18     user='root',
    19     password='llx20190411',
    20     database='youku_one',
    21     charset='utf8',
    22     autocommit='True'
    23 )
    View Code

    文件:mysql_singleton.py

     文件:mysql_singleton.py
     1 import pymysql
     2 from orm_pool import db_pool
     3 
     4 # 封装Mysql
     5 '''
     6 instance实例
     7 connect连接
     8 autocommit自动提交
     9 BaseException基本异常
    10 connect和connection事件功能相似,但是被触发的时间不同.connect先于connetion.
    11 connect是一旦有连接就被触发,而connection在连接完全建立后才被触发.
    12 一般直接如同官网示例那样,直接使用connection事件即可.
    13 但是为了保持与前端的一致性,全部使用connect事件也未尝不可.
    14 参考资料:
    15 https://socket.io/get-started...
    16 https://stackoverflow.com/que...
    17 '''
    18 class Mysql(object):
    19     _instance = None
    20     def __init__(self):
    21         # 连接数据库
    22         self.conn = db_pool.POOL.connection()
    23         # 游标
    24         self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
    25         '''
    26         # 游标
    27         self.cursor = self.conn.cursor()  # 值为元组 ()
    28         # 增加 pymysql.cursors.DictCursor
    29         # 游标
    30         self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)  # 值为 列表套字典
    31         # 变化原因:增加可读性,便于理解
    32         '''
    33 
    34     # 运行一次SQL语句完成需要关闭连接和游标
    35     def close(self):
    36         self.cursor.close()
    37         self.conn.close()
    38 
    39     # 查询
    40     def select(self,sql,args=None):
    41         # 执行
    42         self.cursor.execute(sql,args)
    43         # 取出
    44         res = self.cursor.fetchall()  # 值 列表套字典
    45         return res
    46 
    47     # 执行--防止参数args引起的报错,增加健壮性
    48     def execute(self,sql,args):
    49         try:
    50             self.cursor.execute(sql,args)
    51         except BaseException as e:
    52             print(e)
    mysql_singleton

    文件:orm.py

      1 from orm_pool.mysql_singleton import Mysql
      2 
      3 
      4 # 定义字段类(数据行)
      5 class Field(object):
      6     def __init__(self, name, column_type, primary_key, default):
      7         self.name = name
      8         self.column_type = column_type
      9         self.primary_key = primary_key
     10         self.default = default
     11 
     12 
     13 # 定义具体的字段类(字符串数据行)
     14 class StringField(Field):
     15     def __init__(self, name, column_type='varchar(256)', primary_key=False, default=None):
     16         super().__init__(name, column_type, primary_key, default)
     17 
     18 
     19 class IntegerField(Field):
     20     def __init__(self, name, column_type='int', primary_key=False, default=None):
     21         super().__init__(name, column_type, primary_key, default)
     22 
     23 
     24 # 元类的应用 (通过类来创建类) 这里主要是类创建表进行映射,并且设置限制信息
     25 class ModelMetaClass(type):
     26     '''
     27     __new__方法(重点)
     28 元类中的new方法会在创建类对象时执行,并且先于init方法
     29 作用是创建一个类对象
     30 class A(metaclass=MyMetaClass):
     31 pass
     32 1.执行MyMetaClass的__new__方法   拿到一个类对象
     33 2.执行MyMetaClass的__init__ 方法  传入类对象以及其他的属性 ,进行初始化
     34 
     35 注意:如果覆盖了__new__ 一定也要调用type中的__new__并返回执行结果
     36 
     37 attrs 名称空间
     38     '''
     39 
     40     def __new__(cls, class_name, class_base, class_attrs):
     41         # 我仅仅只想拦截模型表的创建过程(对表的参数进行限制)
     42         if class_name == 'Models':
     43             # 只在这个条件下修改出一个新的类
     44             return type.__new__(cls, class_name, class_base, class_attrs)
     45         # 给类放表名,主键字段,所有字段
     46         # 给类放表名
     47         table_name = class_attrs.get('table_name', class_name)
     48         # 定义一个存储主键的变量
     49         primary_key = None
     50         # 定义一个字典用来存储自定义的表示表的所有字段信息
     51         # 字段 == 列名 + 属性 + 是否有主键索引 + 是否有默认值
     52         mappings = {}
     53         # for循环 当前类的名称空间
     54         for k, v in class_attrs.items():
     55             if isinstance(v, Field):
     56                 mappings[k] = v
     57                 if v.primary_key:
     58                     if primary_key:
     59                         raise TypeError('主键只能有一个')
     60                     primary_key = v.name
     61         # 将mappings 中重复的键值删除
     62         for k in mappings.keys():
     63             # pop 去重
     64             class_attrs.pop(k)
     65         if not primary_key:
     66             raise TypeError('必须要有一个主键')
     67         # 保存修改(将处理好的数据放入'class_attrs'中)
     68         class_attrs['table_name'] = table_name
     69         class_attrs['primary_key'] = primary_key
     70         class_attrs['mappings'] = mappings
     71         return type.__new__(cls, class_name, class_base, class_attrs)
     72 
     73 
     74 # 创建出类,以及他的增删改查
     75 '''
     76 #  反射 -------英文中叫反省 (自省)
     77 1.面向对象中的反省:
     78 指的是,一个对象必须具备,发现自身属性,以及修改自身属性的能力;   
     79 一个对象在设计初期,可能考虑不够周全后期需要删除或修改已经存在的属性, 和增加属性 
     80  # 反射就是通过字符串来操作对象属性
     81  2.涉及到的方法:
     82 ```
     83 hasattr 判断是否存在某个属性
     84 getattr 获取某个属性的值
     85 setattr 新增或修改某个属性 
     86 delattr 删除某个属性 
     87 
     88 # dict 字典可以把所有的值都存储进去
     89 '''
     90 
     91 
     92 class Models(dict, metaclass=ModelMetaClass):
     93     def __init__(self, **kwargs):
     94         super().__init__(**kwargs)
     95 
     96     # 获取表中属性的值
     97     def __getattr__(self, item):
     98         return self.get(item, '没有键值对')
     99 
    100     # 新增或者修改表中的属性
    101     def __setattr__(self, key, value):
    102         self[key] = value
    103 
    104     # 查(**kwargs 条件)
    105     @classmethod
    106     def select(cls, **kwargs):
    107         ms = Mysql()
    108         # select * from userinfo
    109         if not kwargs:
    110             sql = 'select * from %s' % cls.table_name
    111             res = ms.select(sql)
    112         else:
    113             # select * from userinfo where id = 1
    114             # 默认只取一个条件(自己设置一个站为符'?')
    115             k = list(kwargs.keys())[0]
    116             v = kwargs.get(k)
    117             sql = 'select * from %s where %s=?' % (cls.table_name, k)
    118             # select * from userinfo where id = ?
    119             # 用'%s'替换'?'replace()替换
    120             sql = sql.replace('?', '%s')
    121             # select * from userinfo where id = %s
    122             res = ms.select(sql, v)
    123 
    124         # 将数据库的一条数据映射成类的对象
    125         # **r 打散r
    126         if res:
    127             return [cls(**r) for r in res]
    128         # 结果为 # 列名 + 属性 + 是否有主键索引 + 是否有默认值
    129 
    130     #
    131     def save(self):
    132         ms = Mysql()
    133         # insert into userinfo(name,password) values('jason','123')
    134         # insert into %s(%s) values(?)
    135         fields = []  # [name,password]
    136         values = []
    137         args = []
    138         for k, v in self.mappings.items():
    139             # 将id字段去除   因为新增一条数据 id是自动递增的不需要你传
    140             if not v.primary_key:
    141                 fields.append(v.name)  # 列名
    142                 args.append('?')  # 值数量 = 列数量
    143                 values.append(getattr(self, v.name))
    144         # insert into userinfo(name,password) values(?,?)
    145         sql = 'insert into %s(%s) values(%s)' % (self.table_name, ','.join(fields), ','.join(args))
    146         # insert into userinfo(name,password) values(?,?)
    147         # 用'%s'替换'?'replace()替换
    148         sql = sql.replace('?', '%s')
    149         ms.execute(sql,values)
    150         #print(values,'收到吗里去了')
    151 
    152     # 改:基于已经存在了的数据进行一个修改操作
    153     def update(self):
    154         ms = Mysql()
    155         # update userinfo set name='jason',password='123' where id = 1
    156         fields = []  # [name,password]
    157         values = []
    158         pr = None
    159         for k, v in self.mappings.items():
    160             if v.primary_key:
    161                 pr = getattr(self, v.name, v.default)
    162             else:
    163                 fields.append(v.name + '=?')
    164                 values.append(getattr(self, v.name, v.default))
    165         sql = 'update %s set %s where %s = %s' % (self.table_name, ','.join(fields), self.primary_key, pr)
    166         # update userinfo set name='?',password='?' where id = 1
    167         sql = sql.replace('?', '%s')
    168         ms.execute(sql, values)
    169 
    170 
    171 # 运算测试是否正确
    172 if __name__ == '__main__':
    173     pass
    orm

    2.单例orm

    文件夹:orm_singleton

    文件:mysql_singleton.py

     1 import pymysql
     2 
     3 # 封装Mysql
     4 '''
     5 instance实例
     6 connect连接
     7 autocommit自动提交
     8 BaseException基本异常
     9 '''
    10 class Mysql(object):
    11     _instance = None
    12     def __init__(self):
    13         # 连接数据库
    14         self.conn = pymysql.connect(
    15             host = '127.0.0.1',
    16             port = 3306,
    17             user = 'root',
    18             password = 'llx20190411',
    19             datebase = 'youku_one',
    20             charset = 'utf8',
    21             autocommit = True
    22         )
    23         # 游标
    24         self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
    25         '''
    26         # 游标
    27         self.cursor = self.conn.cursor()  # 值为元组 ()
    28         # 增加 pymysql.cursors.DictCursor
    29         # 游标
    30         self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)  # 值为 列表套字典
    31         # 变化原因:增加可读性,便于理解
    32         '''
    33 
    34     # 运行一次SQL语句完成需要关闭连接和游标
    35     def close(self):
    36         self.cursor.close()
    37         self.conn.close()
    38 
    39     # 查询
    40     def select(self,sql,args=None):
    41         # 执行
    42         self.cursor.execute(sql,args)
    43         # 取出
    44         res = self.cursor.fetchall()  # 值 列表套字典
    45         return res
    46 
    47     # 执行--防止参数args引起的报错,增加健壮性
    48     def execute(self,sql,args):
    49         try:
    50             self.cursor.execute(sql,args)
    51         except BaseException as e:
    52             print(e)
    53     # 单例
    54     @classmethod
    55     def singleton(cls):
    56         if not cls._instance:
    57             # 没有则创建新的实例并保存到类中
    58             cls._instance = cls()
    59         return cls._instance
    60 
    61     '''
    62     singleton单例模式---避免重复创建对象,浪费资源,保证程序安全的前提
    63     @classmethod(就是在封装中用'.'直接点出各种使用方式)
    64     一般来说,调用某个类的方法,需要先生成一个实例,再通过实例调用方法。Java中有静态变量,静态方法,可以使用类直接进行调用。Python提供了两个修饰符@staticmethod @classmethod也可以达到类似效果。
    65     单例:
    66     某个类如果只有一个实例对象,那么该类成为单例类 
    67     单例的好处:
    68     当某个类的所有对象特征和行为完全一样时,避免重复创建对象,浪费资源
    69     cls._instance 类的实例
    70     '''
    mysql_singleton

    文件:orm.py

      1 from orm_singleton.mysql_singleton import Mysql
      2 
      3 # 定义字段类(数据行)
      4 class Field(object):
      5     def __init__(self,name,column_type,primary_key,default):
      6         self.name = name
      7         self.column_type = column_type
      8         self.primary_key = primary_key
      9         self.default = default
     10 
     11 # 定义具体的字段类(字符串数据行)
     12 class StringField(Field):
     13     def __init__(self,name,column_type='varchar(256)',primary_key=False,default=None):
     14         super().__init__(name,column_type,primary_key,default)
     15 
     16 class IntegerField(Field):
     17     def __init__(self,name,column_type='int',primary_key=False,default=None):
     18         super().__init__(name,column_type,primary_key,default)
     19 
     20 # 元类的应用 (通过类来创建类) 这里主要是类创建表进行映射,并且设置限制信息
     21 class ModelMetaClass(type):
     22     '''
     23     __new__方法(重点)
     24 元类中的new方法会在创建类对象时执行,并且先于init方法
     25 作用是创建一个类对象
     26 class A(metaclass=MyMetaClass):
     27 pass
     28 1.执行MyMetaClass的__new__方法   拿到一个类对象
     29 2.执行MyMetaClass的__init__ 方法  传入类对象以及其他的属性 ,进行初始化
     30 
     31 注意:如果覆盖了__new__ 一定也要调用type中的__new__并返回执行结果
     32 
     33 attrs 名称空间
     34     '''
     35     def __new__(cls,class_name,class_base,class_attrs):
     36         #我仅仅只想拦截模型表的创建过程(对表的参数进行限制)
     37         if class_name == 'Models':
     38             # 只在这个条件下修改出一个新的类
     39             return type.__new__(cls,class_name,class_base,class_attrs)
     40         # 给类放表名,主键字段,所有字段
     41         # 给类放表名
     42         table_name = class_attrs.get('table_name',class_name)
     43         # 定义一个存储主键的变量
     44         primary_key = None
     45         # 定义一个字典用来存储自定义的表示表的所有字段信息
     46         # 字段 == 列名 + 属性 + 是否有主键索引 + 是否有默认值
     47         mappings={}
     48         # for循环 当前类的名称空间
     49         for k,v in class_attrs.items():
     50             if isinstance(v,Field):
     51                 mappings[k] = v
     52                 if v.primary_key:
     53                     if primary_key:
     54                         raise TypeError('主键只能有一个')
     55                     primary_key = v.name
     56         # 将mappings 中重复的键值删除
     57         for k in mappings.keys():
     58             # pop 去重
     59             class_attrs.pop(k)
     60         if not primary_key:
     61             raise TypeError('必须要有一个主键')
     62         # 保存修改(将处理好的数据放入'class_attrs'中)
     63         class_attrs['table_name'] = table_name
     64         class_attrs['primary_key'] = primary_key
     65         class_attrs['mappings'] = mappings
     66         return type.__new__(cls,class_name,class_base,class_attrs)
     67 
     68 # 创建出类,以及他的增删改查
     69 '''
     70 #  反射 -------英文中叫反省 (自省)
     71 1.面向对象中的反省:
     72 指的是,一个对象必须具备,发现自身属性,以及修改自身属性的能力;   
     73 一个对象在设计初期,可能考虑不够周全后期需要删除或修改已经存在的属性, 和增加属性 
     74  # 反射就是通过字符串来操作对象属性
     75  2.涉及到的方法:
     76 ```
     77 hasattr 判断是否存在某个属性
     78 getattr 获取某个属性的值
     79 setattr 新增或修改某个属性 
     80 delattr 删除某个属性 
     81 
     82 # dict 字典可以把所有的值都存储进去
     83 '''
     84 
     85 class Models(dict,metaclass=ModelMetaClass):
     86     def __init__(self,**kwargs):
     87         super().__init__(**kwargs)
     88 
     89     #获取表中属性的值
     90     def __getattr__(self,item):
     91         return self.get(item,'没有键值对')
     92 
     93     # 新增或者修改表中的属性
     94     def __setattr__(self, key, value):
     95         self[key] = value
     96 
     97     # 查(**kwargs 条件)
     98     @classmethod
     99     def select(cls,**kwargs):
    100         ms=Mysql.singleton()
    101         # select * from userinfo
    102         if not kwargs:
    103             sql = 'select * from %s' % cls.table_name
    104             res = ms.select(sql)
    105         else:
    106             # select * from userinfo where id = 1
    107             # 默认只取一个条件(自己设置一个站为符'?')
    108             k = list(kwargs.keys())[0]
    109             v = kwargs.get(k)
    110             sql = 'select * from %s where %s=?' % (cls.table_name,k)
    111             # select * from userinfo where id = ?
    112             #用'%s'替换'?'replace()替换
    113             sql = sql.replace('?','%s')
    114             # select * from userinfo where id = %s
    115             res = ms.select(sql,v)
    116 
    117         # 将数据库的一条数据映射成类的对象
    118         # **r 打散r
    119         if res:
    120             return [cls(**r) for r in res]
    121         # 结果为 # 列名 + 属性 + 是否有主键索引 + 是否有默认值
    122 
    123     #
    124     def save(self):
    125         ms = Mysql.singleton()
    126         # insert into userinfo(name,password) values('jason','123')
    127         # insert into %s(%s) values(?)
    128         fields = []  # [name,password]
    129         values = []
    130         args = []
    131         for k,v in self.mappings.items():
    132             # 将id字段去除   因为新增一条数据 id是自动递增的不需要你传
    133             if not v.primary_key:
    134                 fields.append(v.name)  # 列名
    135                 args.append('?')  # 值数量 = 列数量
    136                 values.append(getattr(self,v.name))
    137         # insert into userinfo(name,password) values(?,?)
    138         sql = 'insert into %s(%s) values(%s)'%(self.table_name,','.join(fields),','.join(args))
    139         # insert into userinfo(name,password) values(?,?)
    140         # 用'%s'替换'?'replace()替换
    141         sql = sql.replace('?', '%s')
    142         ms.execute(sql.values)
    143 
    144     # 改:基于已经存在了的数据进行一个修改操作
    145     def update(self):
    146         ms = Mysql.singleton()
    147         # update userinfo set name='jason',password='123' where id = 1
    148         fields = []  # [name,password]
    149         values = []
    150         pr = None
    151         for k, v in self.mappings.items():
    152             if v.primary_key:
    153                 pr = getattr(self, v.name, v.default)
    154             else:
    155                 fields.append(v.name + '=?')
    156                 values.append(getattr(self, v.name, v.default))
    157         sql = 'update %s set %s where %s = %s' % (self.table_name, ','.join(fields), self.primary_key, pr)
    158         # update userinfo set name='?',password='?' where id = 1
    159         sql = sql.replace('?', '%s')
    160         ms.execute(sql, values)
    161 
    162 
    163 # 运算测试是否正确
    164 if __name__=='__main__':
    165     pass
    orm
  • 相关阅读:
    SpringBoot处理跨域的四种方式
    centos部署nextcloud
    nginx反向代理时配置访问密码
    java对redis的基本操作
    springboot使用redis
    Linux安装redis
    centos安装php7.2环境 (亲测可用)
    linux下后台启动springboot项目
    全局加token
    web移动端浮层滚动阻止window窗体滚动JS/CSS处理
  • 原文地址:https://www.cnblogs.com/llx--20190411/p/11116055.html
Copyright © 2011-2022 走看看