浮躁是人生最大的敌人

ORM——对象关系映射01

Posted on 2019-05-20 22:59  King'home  阅读(166)  评论(0编辑  收藏  举报

数据库连接

import pymysql

class Mysql(object):
_instance = None
def init(self):
self.conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
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)
    res = self.cursor.fetchall()  # 注意一点:fetchall拿到的数据结构是一个列表套字典[{},{},{}]
    return res

def execute(self,sql,args):
    # insert into user(name,password) values('jason','123')
    # update user set name='jason',passsword='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

ORM 代码

from mysql_signleton import Mysql

定义字段的父类,参数包括:字段名,类型,主键,默认值

class Field(object):
def init(self, name, colum_type, primary_key, default):
self.name = name
self.colum_type = colum_type
self.primary_key = primary_key
self.default = default

定义字符串类型的字段类

class StringField(Field):
def init(self, name, colum_type='varchar(32)', primary_key=False, default=None):
super().init(name,colum_type,primary_key,default)

定义整型了类型字段

class IntField(Field):
def init(self,name,colum_type='int',primary_key = False, default = None):
super().init(name,colum_type,primary_key,default)

class MyMetaClass(type):
def new(cls,class_name,class_bases,class_attrs):
# 定义的元类的是用来拦截modle的创建过程,modles并不是一个模型表,不需要创建过程
if class_name =='Modles':
return type.new(class_name,class_bases,class_attrs)
# 创建一个表,如果有新表名就用表名,没有就默认用类名
table_name = class_attrs.get('table_name',class_name)
primary_key = None
mappings = {}

    for k,v in class_attrs.items(): # k: id,name v:IntField(),StringField()
        # 拿出所有自定义的表的字段属性
        if isinstance(v,Field):
            # 将所有的自定义的表的字段存入字典中
            mappings[k]=v
            # 检验表的主键
            if v.primary_key:
				# 每个表只有一个主键
                if primary_key:
                    raise TypeError('一张表只有一个属性')
                primary_key = v.name

    for k in mappings.keys():
        # 将单个字段删除
        class_attrs.pop(k)
    # 检验用户自定义模型表是否指定主键字段
    if not primary_key:
        raise TypeError('一张表必须要有主键')
    # 将标示表的特征信息,表名,表的主键字段,表的其他字段都塞到类的名称空间中
    class_attrs['table_name'] = table_name
    class_attrs['primary_key'] = primary_key
    class_attrs['mapping'] = mappings
    return type.__new__(cls,class_name,class_bases,class_attrs)

辅助类:方便实例化对象使用点方法,直接调用属性

class Modles(dict, metaclass=MyMetaClass):
# 继承字典的方法
def init(self,kwargs):
super().init(
kwargs)

# 获取字典对应的值self = 字典
def __getattr__(self, item):
    return self.get(item,'没有该键')

# 修改属性值
def __setattr__(self, key, value):
    self[key] = value


@classmethod
def select(cls,**kwargs):
    ms = Mysql.singleton()

    if not kwargs:
        sql = 'select * from %s'%cls.table_name
        res = ms.select(sql)

    else:
        k = list(kwargs.keys())[0] # .keys 不能直接取值,可以迭代取值
        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:
        return [cls(**r) for r in res]

if name == 'main':
class Teacher(Modles):
table_name = 'teacher'
tid = IntField(name='tid', primary_key=True)
tname = StringField(name='tname')

t1 = Teacher(tname='king',tid=1)
print(t1.tname)
print(t1.tid)

Copyright © 2024 King'home
Powered by .NET 8.0 on Kubernetes