ORM对象关系映射--------简单的底层实现(单表的增删该查)

CustomORM.py

from Mysql_single import Mysql


class Fileld(object):
    '''
    Fileld是父类
    '''

    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


class IntegerFileld(Fileld):
    '''
    IntegerFileld  数字类
    '''

    def __init__(self, name=None, column_type="int", primary_key=False, default=0):
        super().__init__(name, column_type, primary_key, default)


class CharFileld(Fileld):
    '''
    CharFileld 字符串类
    '''

    def __init__(self, name=None, column_type="varchar(200)", primary_key=False, default=None):
        super().__init__(name, column_type, primary_key, default)


class ModelsMeta(type):
    def __new__(cls, name, bases, attrs):
        # print(name) # 类名
        # print(bases) # 父类
        # print(attrs) # 名称空间,是个字典
        # print("=" * 50)
        # 因为models是元类的对象,需要实例化
        if name == 'Models':
            return type.__new__(cls, name, bases, attrs)
        table_name = attrs.get('table_name', None)
        if not table_name:
            table_name = name
        # 主键
        primary_key = None
        # 一个个的列,是对象
        mappings = dict()

        for k, v in attrs.items():
            # 这里的k相当于id,v相当于IntegerFileld()的对象,一定继承Fileld
            if isinstance(v, Fileld):
                mappings[k] = v
                # 判断对象的primary_key是否是True,是的话,把对象.name赋值给primary_key
                if v.primary_key:
                    if primary_key:
                        raise TypeError("主键重复:%s" % k)
                    primary_key = k

        # 把attrs里面的全部删除
        for k in mappings.keys():
            attrs.pop(k)

        if not primary_key:
            raise TypeError("没有主键")

        attrs['table_name'] = table_name
        attrs['primary_key'] = primary_key
        attrs['mappings'] = mappings
        # print(attrs)
        return type.__new__(cls, name, bases, attrs)


class Models(dict, metaclass=ModelsMeta):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def __getattr__(self, item):
        '''
        取的时候用这个方法
        '''
        try:
            return self[item]
        except KeyError:
            raise AttributeError('没有属性:%s' % item)

    def __setattr__(self, key, value):
        '''
        存的时候用这个方法
        '''
        self[key] = value

    @classmethod
    def select_one(cls, **kwargs):
        '''
        查询一条
        :param kwargs: 类似{id:1}
        :return:
        '''
        key = list(kwargs.keys())[0]
        value = kwargs[key]
        sql = "select * from %s where %s=?" % (cls.table_name, key)
        sql = sql.replace('?', '%s')
        ms = Mysql().singleton()
        res = ms.select(sql, value)
        if res:
            # re是一个列表,列表里面套一个字典
            return cls(**res[0])
        else:
            return

    @classmethod
    def select_all(cls, **kwargs):
        '''
        查询所有
        '''
        ms = Mysql().singleton()
        if kwargs:
            key = list(kwargs.keys())[0]
            value = kwargs[key]
            sql = "select * from %s where %s=?" % (cls.table_name, key)
            sql = sql.replace('?', '%s')
            res_list = ms.select(sql, value)
        else:
            sql = "select * from %s" % cls.table_name
            res_list = ms.select(sql, None)

        return [cls(**r) for r in res_list]

    def update(self):
        '''
        更新
        '''
        ms = Mysql().singleton()
        fields = []
        args = []
        pk = None
        # update user set name=?,password=? where id=1
        for k, v in self.mappings.items():
            if v.primary_key:
                pk = getattr(self, k, v.default)
            else:
                fields.append(v.name + "=?")
                args.append(getattr(self, k, v.default))
        sql = "update %s set %s where %s = %s " % (self.table_name, ','.join(fields), self.primary_key, pk)
        sql = sql.replace('?', '%s')
        ms.extcute(sql, args)

    def save(self):
        '''
        插入新的记录
        '''
        ms = Mysql().singleton()
        try:
            # insert into user(%s,%s) values (?,?)
            fields = []
            args = []
            values = []
            for k, v in self.mappings.items():
                fields.append(v.name)
                args.append(getattr(self, v.name, None))
                values.append('?')

            sql = "insert into %s (%s) values (%s)" % (self.table_name, ','.join(fields), ','.join(values))
            sql = sql.replace("?", "%s")
            ms.extcute(sql, args)
        except Exception as e:
            print(e)


class User(Models):
    table_name = 'user'
    id = IntegerFileld('id', primary_key=True)
    password = CharFileld('password')


if __name__ == '__main__':
    # user = User.select_one(id=1)
    # print(user.name)

    user_list = User().select_all()
    print(user_list)

Mysql_single.py

import pymysql

class Mysql:
    __instance = None
    def __init__(self):
        self.conn = pymysql.connect(
            host = '127.0.0.1',
            port = 3306,
            user = 'root',
            password = '',
            database = 'youku',
            autocommit = True
        )
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)


    def close(self):
        self.cursor.close()
        self.conn.close()

    def select(self,sql,args):
        '''
        查询
        '''
        self.cursor.execute(sql,args)
        re = self.cursor.fetchall()
        return re

    def extcute(self,sql,args):
        '''
        更新,保存
        '''
        try:
            self.cursor.execute(sql,args)
            row = self.cursor.rowcount
            return row
        except BaseException as e:
            print(e)

    @classmethod
    def singleton(cls):
        if not cls.__instance:
            cls.__instance = cls()
        return cls.__instance





ms = Mysql()

# if __name__ == '__main__':
#
#     m = Mysql()
#     res = m.select("select * from user where id = %s", 1)
#     print(res)

猜你喜欢

转载自blog.csdn.net/qq_42721964/article/details/86756708