zoukankan      html  css  js  c++  java
  • 手撸ORM系列

    手撸ORM系列

    实现了简单的orm框架,在封装好的pymysql及基础上,通过类与对象操作pymysql,对数据库进行管理与一些简单操作。

    啥也不说,直接上代码!!!

    one

    封装好pymysql,是实现orm的基本。

    # mysql_control.py
    
    import pymysql
    
    class Mysql:
        # 单例模式
        __instance = None
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                cls.__instance = object.__new__(cls)
            return cls.__instance
    
        def __init__(self):
            self.mysql = pymysql.connect(
                host='127.0.0.1',
                port=3306,
                user='root',
                password='root',
                database='orm_demo',
                charset='utf8',
                autocommit=True
            )
            self.cursor = self.mysql.cursor(pymysql.cursors.DictCursor)
    
        def select(self, sql, args=None):
            print(sql)
            print(args)
            # 提交select语句
            self.cursor.execute(sql, args)
    
            # 获取查询结果
            res = self.cursor.fetchall()
            return res
    
        # 提交
        def execute(self, sql, args):
    
            try:
                print(sql)
                print(args)
                self.cursor.execute(sql, args)
    
            except Exception as e:
                print(e)
    
        def close(self):
            self.cursor.close()
            self.mysql.close()
    

    two

    封装基本的表字段,简单实现了整型与字符串类型。

    # orm.py
    
    class Field:
        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 IntegerField(Field):
        def __init__(self, name, column_type='int', primary_key=False, default=None):
            super().__init__(name, column_type, primary_key, default)
    
    
    class StringField(Field):
        def __init__(self, name, column_type='varchar(64)', primary_key=False, default=None):
            super().__init__(name, column_type, primary_key, default)
    

    three

    操作pymysql,实现简单的数据库操作。

    # orm.py
    
    class Model(dict, metaclass=Myorm):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
    
        def __getattr__(self, item):
            return self.get(item)
    
        def __setattr__(self, key, value):
            self[key] = value
    
        @classmethod
        def select(cls, **kwargs):
            mysql = mysql_control.Mysql()
            if not kwargs:
                sql = 'select * from %s' % cls.table_name
                res = mysql.select(sql)
            else:
                key = list(kwargs.keys())[0]
                value = kwargs.get(key)
                sql = 'select * from %s where %s=?' % (cls.table_name, key)
                sql = sql.replace('?', '%s')
                res = mysql.select(sql, value)
            return [cls(**r) for r in res]
    
        def save(self):
            mysql = mysql_control.Mysql()
            fields = []
            values = []
            replace = []
            print(self.mappings)
            for k, v in self.mappings.items():
                fields.append(k)
    
                values.append(
                    getattr(self, v.name, v.default)
                )
                replace.append('?')
            sql = 'insert into %s(%s) values(%s)' % (self.table_name, ','.join(fields), ','.join(replace))
            sql = sql.replace('?', '%s')
            mysql.execute(sql, values)
    
        def sql_update(self):
            mysql = mysql_control.Mysql()
            fields = []
            values = []
            primary_key = False
            for k, v in self.mappings.items():
                if v.primary_key:
                    primary_key = getattr(self, v.name)
                else:
                    fields.append(v.name + '+?')
                    values.append(getattr(self, v.name))
            sql = 'update %s set %s where %s=%s' % (self.table_name, ','.join(fields), self.primary_key, primary_key)
    
            sql = sql.replace('?', '%s')
            mysql.execute(sql, values)
    

    four

    通过元类,限制表名,主键数量,名称空间。

    # orm.py
    
    class Myorm(type):
        def __new__(cls, class_name, class_base, class_attr):
            if class_name == 'Model':
                return type.__new__(cls, class_name, class_base, class_attr)
            table_name = class_attr.get('table_name', class_name)
            primary_key = False
            mappings = {}
            for k, v in class_attr.items():
                if isinstance(v, Field):
                    mappings[k] = v
                    if v.primary_key:
                        if primary_key:
                            raise TypeError('只能有一个主键')
                        primary_key = v.name
    
            for key in  mappings.keys():
                class_attr.pop(key)
    
            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_base, class_attr)
    

    five

    到此完事!!!

  • 相关阅读:
    回来了
    【Docker】Docker学习笔记:shipyard使用
    【Docker】Docker学习笔记:安装部署
    【LVS】LVS用windows作为realserver的设置方法
    【linux常用命令】linux命令工具基础
    【linux工具】crontab
    【开源软件】windows环境下libcurl编译
    【工作笔记】CPU亲和性
    【转】多线程or多进程
    【学习笔记】git常用命令
  • 原文地址:https://www.cnblogs.com/dadazunzhe/p/12597969.html
Copyright © 2011-2022 走看看