python 用元类 type 实现对数据库的ORM 映射

python 实现对数据库的ORM 映射

如果使用pymysql 操作数据库 不借助框架的话,频繁写sql语句, 的确比较麻烦
这里借助 type 元类 对 数据表类实现了 与mysql之间的 映射

直接上代码

import pymysql

def conn_database_execute(sql_str):
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='123', database='it_test',
                           charset='utf8')
    cus = conn.cursor()
    get_exist_tables = 'show tables;'
    cus.execute(get_exist_tables)
    ret = cus.fetchall()
    print(ret)
    if sql_str.startswith('create'):
        sql_str_list = sql_str.split(' ')
        print(sql_str_list)
        table_name = sql_str_list[2]
        if not (table_name,) in ret:
            print(' create a table ')
            cus.execute(sql_str)
    else:
        cus.execute(sql_str)
    print('===============================')
    print(sql_str)
    print('===============================')
    cus.close()
    conn.close()

class MetaClassModel(type):
    def __new__(cls, cls_name, args, kwargs):
        mapping = dict()
        field_name_explain = dict()
        for k, v in kwargs.items():
            if isinstance(v, tuple):
                mapping[k] = v
                field_name_explain[ v[0] ] = v[1]

        for k in mapping.keys():
            kwargs.pop(k)

        kwargs['mapping_'] = mapping
        # mapping_ = {
        #   user_id = ('user_id', 'int unsigned auto_increment primary key not null'),
        #   name = ('name', 'varchar(20)')
        #   age = ('age', 'int unsigned')
        # }
        kwargs['table_'] = cls_name
        if cls_name != 'Model':
            sql_str_1 = ''
            for field_name, field_explain in field_name_explain.items():
                print(type(field_name))
                print(type(field_explain))
                sql_str_1 += field_name + ' ' + field_explain +','
            sql_str_1 = sql_str_1[:-1]
            create_sql_str = "create table %s (%s);" %(cls_name, sql_str_1)
            print(create_sql_str)
            conn_database_execute(create_sql_str)
        return type.__new__(cls, cls_name, args, kwargs)

class Model(metaclass=MetaClassModel):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

    def save(self):
        files = []
        args = []
        for key, vaule in self.mapping_.items():
            files.append(vaule[0])

            # 获取通过(构造方法 里面 setattr设置的参数value)
            args.append(getattr(self, key, None))

        args_temp = list()
        for temp in args:
            if isinstance(temp, int):
                args_temp.append(str(temp))
            elif isinstance(temp, str):
                args_temp.append(
                    """'%s'"""%temp
                )

        sql_str = 'insert into %s (%s) values (%s);'%(self.table_, ','.join(files), ','.join(args_temp))
        print(sql_str)
        conn_database_execute(sql_str)

class User(Model):
    user_id = ('user_id', 'int unsigned auto_increment primary key not null')
    name = ('name', 'varchar(20)')
    age = ('age', 'int unsigned')
    # mapping_ = {
    #   user_id = ('user_id', 'int unsigned auto_increment primary key not null'),
    #   name = ('name', 'varchar(20)')
    #   age = ('age', 'int unsigned')
    # }

# user_1 = User(user_id=0, name='WangMing', age=6)
# user_1.save()
# user_2 = User(user_id=0, name='LiQiang', age=7)
# user_2.save()
class SuperUser(Model):
    user_id = ('user_id', 'int unsigned auto_increment primary key not null')
    name = ('name', 'varchar(20)')
    age = ('age', 'int unsigned')

user_2 = User(user_id=0, name='MengTing', age=7)
user_2.save()

只要定义一个类继承 Model类, 就可以在数据库中创建相应的表,
但是还有个问题user.save() 明明生成了正确的sql语句, 却没有成功插入,不知道怎么回事, 希望路过的大哥告诉我一下,小弟不胜感激!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值