youku项目总结(粗略总结)

一、ORM

之前我们都是以文件保存的形式存储数据,这次我们用的是数据库结合python使用,用到

ORM:关系型映射

类》》数据库的一张表

对象》》表一条记录

对象.属性》》记录某一个字段对应的值

关于ORM我们其实可以调用别人已经写好的,这次我们是自己写ORM。

这个就是在Django中调用别人的写好的

1.先设计字段类型(这次只会用到两个字段类型,所以只设计两个)

字段:字段名、字段类型、是否为主键、默认值

#定义字段类型  name,column_type,primary_key,default   (字段名,字段类型,主键,默认值)
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

#下面这些类型也可以不定义,但是你每次调用Field的时候,每个参数值都需要写
#定义varchar字段类型(针对于字段类型是varchar的)
class StringField(Field):
    def __init__(self,name,column_type = 'varchar(32)',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)

2.设计模型表

继承字典类型,可以接收任意个数的关键字参数

所有模型表都继承Models,Models继承dict,__getattr__是当通过对象.属性的方式取值,属性不存在的话,就会触发这个方法

__setattr__是当新增或者修改属性的时候就会触发这个方法

class Models(dict,metaclass = Mymetaclass)
    def __init__(self,**kwargs): #接收任意多个关键字参数
        super().__init__(**kwargs)  #继承dict
        
    def __getattr__(self, item):  #item是不存在的属性名  self是一个字典对象
        return self.get(item)

    def __setattr__(self, key, value):  #新增或者修改属性都会走这个
        self[key] = value

3.使用元类,拦截自定义模型表的创建过程

使用元类,在类创建的时候把表名、字段、主键塞给类

类在创建的三个步骤:

1.__new__产生一个空对象

2.__init__实例化

3.将产生的对象返回

class MyMetaclass(type):  #需要设置表名,主键,字段
    def __new__(cls,class_name,class_bases,class_attr):   #__new__创建一个空对象,class_name(类名),class_bases(基类们),class_attr(名称空间)
        #自定义元类是拦截模型表的创建过程,而models并不是一张模型表,所以不需要它的创建过程
        if class_name == 'Models':
            return type.__new__(cls,class_name,class_bases,class_attr) #如果是models直接返回type
        table_name = class_attr.get('table_name',class_name)  #获取名称空间内的表名,没有就返回类名
        primary_key = None
        mappings = {}  #方便后面取值
        for k,v in class_attr.items():  #循环获取名称空间的所有键值对 k:id,name   v:IntegerField(),StringField()是对象
            if isinstance(v,Field):  #拿出所有自定义的字段属性
                #将所有自定义表的字段全部存入字典中
                mappings[k] = v
                if v.primary_key:  #判断字段是否存在主键
                    if primary_key:
                        raise TypeError('一张表只能存在一个主键')
                    primary_key = v.name   #设置主键字段名
        #循环取出mappings的key(也就是自定义的字段名),因为后面要把自定义的mappings放进class_attr里面,为了节省空间所以把原来的键值对删除
        for k in mappings.keys():
            class_attr.pop(k)   #将名称空间内的重复k,v键值对删除
        #校验自定义的的表是否指定了主键字段
        if not primary_key:
            raise TypeError('一张表必须要有一个主键')


        class_attr['table_name'] = table_name
        class_attr['primary_key'] = primary_key
        class_attr['mappings'] = mappings

        return type.__new__(cls,class_name,class_bases,class_attr)

4.结合pymsql模块,封装查询和提交语句

import pymysql
from orm.db_pool import POOL
class Mysql:
    def __init__(self):
        self.conn =POOL.connection()
        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)
        res = self.cursor.fetchall()  #查询所有  [{},{},{}....]
        return res

    #封装提交
    def myexecute(self,sql,args):
        try:
            self.cursor.execute(sql,args)
        except Exception as e:
            print(e)

二、项目书写

项目是由服务端和客户端组成,基于socket通信

 未完

猜你喜欢

转载自www.cnblogs.com/wangcuican/p/11433323.html