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

python 实现对数据库的ORM 映射

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

直接上代码

import pymysqldef 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] = vfield_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_nameif 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语句, 却没有成功插入,不知道怎么回事, 希望路过的大哥告诉我一下,小弟不胜感激!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言模拟实现标准库函数之memcpy()

memcpy() 1.如果我们需要对一个数组初始化,把数组的内容全部置0,那么能不能用strcpy() int main() {char arr1[10] { 0 };char arr2[10] " abcdefg ";strcpy(arr2, arr1);system("pause");return 0; } 我…

说说堆及堆排序

堆:是一种数组对象,它可以被看成是一种二叉树结构。 我们把堆的二叉树存储方式分为两种:即大堆和小堆。那么问题来了,什么大堆?什么是小堆? 大堆:让每个父节点的值都大于孩子节点的值。 小堆…

运算符优先级 速查表

运算符优先级 优先级【高到低】: 第一级: 圆括号【()】、下标运算符【[]】、分量运算符的指向结构体成员运算符【->】、结构体成员运算符【.】 第二级: 逻辑非运算符【!】、按位取反运算符【~】、自增自减运…

linux--几种常见的进程调度算法

进程调度:在操作系统中调度是指一种资源分配,因而调度算法是指:根据系统的资源分配策略所规定的资源分配算法。操作系统管理了系统的有限资源,当有多个进程(或多个进程发出的请求)要使用这些资源时,因为资源的有限性,必…

指针数组和数组指针和函数指针

文章目录1.指针数组和数组指针1.int *p1[10];2.int (*p2)[10];2.函数指针char *(*fun1)(char * p1,char *p2)函数指针的概念函数指针的作用:例子1 .调用方式例子2:(带注释)例子33.做题的小技巧1.指针数组和数组指针 1.int *p1[10…

使用虚拟环境virtualenv 创建虚拟环境出现PermissionError: [Errno 13] Permission denied:

使用虚拟环境virtualenv 创建虚拟环境出现PermissionError: [Errno 13] Permission denied: 原因:虚拟环境安装的目录所属用户非当前用户 解决办法:将目录及其文件的所有者改为当前用户 解决命令:sudo chown -R 当前用户 待更改用户的目录/ …

linux之父子进程的输出

首先,我们来回忆一下父进程与子进程,前几节讲了如何创建子进程,像这样的,pid_t id fork(); 这样我们就创建好了一个子进程,然而fork()函数的返回值是什么呢?这里要记住:子进程返回0&#xff0c…

linux---谈谈vfork和fork的区别及exit与return

fork():创建子进程的函数,是大家比较熟悉的吧。pid_t id fork(); 这里的vfork();也是创建子进程的函数。现在我们来剖析一下它们吧。 第一例: 先看一个fork()的例子哦。 对于fork()而言,创建子进程成功后直接打印出父子进程执…

在MySQL数据库建立多对多的数据表关系

转载自 https://blog.51cto.com/13145200724/1370753

C语言模拟实现标准库函数之qsort()

qsort 编译器函数库自带的快速排序函数。 void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*)); 参数解释: void*base-待排序数组首地址size_t num-数组中待排序元素数量size_t width-各元素的占用空间大小int(__cde…

django contrib 包简介

转自 https://www.cnblogs.com/tianboblog/p/6955297.html

linux之管道

管道(PIPE)是linux中一个重要的通信方式,在进程中,我们通过从一个进程中读取到的数据转到另一个进程中的写数据中,这时就要有不同的进程之间共享同一份资源,就是所谓的进程间通信。由于进程的特点是资源独占…

把student a am i 变成 i am a student(两种方法)

文章目录#student a am i 变成 i am a student##方法1&#xff1a;指针#include <stdlib.h> #include <stdio.h> #include <string.h>void fanw(char *l, char *r) {char* left l;char* right r;char temp;while (left < right){temp *left;*left *ri…

关掉占用 某端口的进程

sudo fuser -k 8000/tcp 这样和端口8000相关的进程就都关了。

linux之多线程(1)

我们之前讲了进程&#xff0c;今天我们重新认识另外一个概念---线程。我们首先会想到的是进程和线程有什么区别和联系&#xff0c;对吧&#xff1f;进程是由程序执行起来&#xff0c;跑在操作系统的&#xff0c;是系统进行资源分配和调度的基本单位。进程具有资源独占性&#x…

C语言typedef与#define的区别

typedef和#define define 没有参加编译&#xff0c;在预处理的时候就被替换掉了。 typedef参加编译和链接。typedef是重命名&#xff0c;可以为枚举结构体等等重新命名&#xff0c;提高代码整洁。 一、typedef的用法 C语言中&#xff0c;typedef常用来定义一个标识符及关键…

django models模型 内部类 class Meta 简介

class Meta: #这个属性是定义当前的模型类是不是一个抽象类。所谓抽象类是不会相应数据库表的。一般我们用它来归纳一些公共属性字段&#xff0c;然后继承它的子类能够继承这些字段。abstractTrue #db_table是用于指定自己定义数据库表名的db_table test#因为Django的管理方法…

阻断血缘关系以及checkpoint文件清理

spark-sql读写同一张表&#xff0c;报错Cannot overwrite a path that is also being read from 1. 增加checkpoint&#xff0c;设置检查点阻断血缘关系 sparkSession.sparkContext.setCheckpointDir("/tmp/spark/job/OrderOnlineSparkJob")val oldOneIdTagSql s&…

linux之睡眠函数(my_sleep)

我们在程序中&#xff0c;很多次用到sleep()函数&#xff0c;让它睡眠几秒后再执行该进程。今天呢&#xff0c;我要给大家实现一下sleep函数。 看看代码哦&#xff1a; 运行结果&#xff1a; 结果中每隔三秒钟&#xff0c;打印一条语句。实现了sleep(3)的功能。 关于sleep函数…

C语言 防止头文件被多次引用

comm.h和comm.c是公共模块。 test1.h和test1.c使用了公共模块。 test2.h和test2.c使用了了公共模块。 test.h和test.c使⽤用了了test1模块和test2模块。 这样最终程序中就会出现两份comm.h的内容。这样就造成了了文件内容的重复。 1.方法1 文件开头加上这一句就ok #prag…