用元类去实现orm

def insert(self, **kwargs):
		print(kwargs)

		# 循环去我们的字典中去拼接一个字段列表,一个值列表
		field_list = list()
		value_list = list()

		for key, value in kwargs.items():
			field_list.append(key)
			value_list.append(""" '%s' """ % str(value))  # 这个字符串里面加引号

		# 1 连接数据
		# 创建Connection连接
		conn = connect(host='localhost', port=3306, database='jing_dong', user='root', password='mysql', charset='utf8')
		# 获得Cursor对象
		cs1 = conn.cursor()

		# 2.执行sql语句
		sql = """ insert into %s(%s) values(%s); """ % (self.table_name, ",".join(field_list), ",".join(value_list))
		print(sql)
		cs1.execute(sql)

		# 提交
		conn.commit()

		# 3.关闭
		cs1.close()
		conn.close()

def insert(self, **kwargs):
		print(kwargs)

		# 循环去我们的字典中去拼接一个字段列表,一个值列表
		field_list = list()
		value_list = list()

		for key, value in kwargs.items():
			field_list.append(key)
			value_list.append(""" '%s' """ % str(value))  # 这个字符串里面加引号

		# 1 连接数据
		# 创建Connection连接
		conn = connect(host='localhost', port=3306, database='jing_dong', user='root', password='mysql', charset='utf8')
		# 获得Cursor对象
		cs1 = conn.cursor()

		# 2.执行sql语句
		sql = """ insert into %s(%s) values(%s); """ % (self.table_name, ",".join(field_list), ",".join(value_list))
		print(sql)
		cs1.execute(sql)

		# 提交
		conn.commit()

		# 3.关闭
		cs1.close()
		conn.close()

今天学习了元类,发现了一招用元类操作数据库神奇的方法,以后繁杂的sql语句要拜拜啦,我来分享下这个方法。
这是一段很普通的通过mysql创建表的代码,我们把表的属性通过格式化输出到%s里,用字典保存起来,再放进一个列表里,然后用逗号分隔开来,这样就和原来创建sql的语句一样了。但是我们觉得很繁琐,所以将属性值和表名在方法外定义
	fields_dict = {"uid": "int unsigned", "pwd": "varchar(30)"}
	table_name = "abc"

for key, value in self.fields_dict.items():
			fields_list.append("%s %s" % (key, value))

		# 2.执行sql语句
		# sql = """ CREATE TABLE IF NOT EXISTS user(uid int unsigned,name varchar(30),email varchar(30),password varchar(30)); """
		sql = """ CREATE TABLE IF NOT EXISTS %s(%s); """ % (self.table_name, ",".join(fields_list))
		print(sql)

还是很繁琐,我们就祭出大招,用元类去创建我们的字典。

class ChangeClass(type):
    def __new__(cls, class_name, super_names, attrs):
        print(attrs)
        # 一个新的字典
        fields_dict = dict()

        # 去我们的属性字典,判断如果是元组的,那么就是我们写的属性
        for key, value in attrs.items():
            if isinstance(value, tuple):
                # 到这里说明是我们定义的属性
                fields_dict[key] = value[0]

        # 添加到我们的属性字典中
        attrs['fields_dict'] = fields_dict
        return type.__new__(cls, class_name, super_names, attrs)


# 元类让我们的写法很爽,用的时候也很爽
class User(object, metaclass=ChangeClass):
    uid = ("int unsigned",)
    name = ("varchar(30)",)
    age = ("int",)
    info = ("varchar(30)",)

    # fields_dict = {"uid": "int unsigned", "pwd": "varchar(30)"}
    table_name = "user"
因为之前我们的属性值是字符串,所以我们将他们改造为元组,然后通过遍历元类中的attrs,用isinstance去判断属性值是否是元组,如果是通过value[0]去获取元组内的值,添加到属性字典中。但是这样感觉还不是很爽,如果换一张表,又要重新写创建表的代码,所以我又想到了下面一个办法,我们可以把共同的方法抽取到一个父类中,在属性字典中添加表名,表名就是类名attrs['table_name'] = class_name。然后将原来的class User():改为class table():
class Student(Table):
	name = ("varchar(30)",)
	age = ("int",)
通过一个子类去继承它,甚至我们可以用创建一个Field类去控制它,让我们能将
name = ("varchar(30)",)
改为
name = Field("varchar(30)"
然后定义一个Field的方法
class Field(object):
	def __init__(self, args):
		self.args = args


class ChangeClass(type):
	def __new__(cls, class_name, super_names, attrs):
		print(attrs)
		# 一个新的字典
		fields_dict = dict()

		# 去我们的属性字典,判断如果是元组的,那么就是我们写的属性
		for key, value in attrs.items():
			if isinstance(value, Field):
				# 到这里说明是我们定义的属性
				fields_dict[key] = value.args

将tuple改为Field函数的引用,通过value.args去调用我们Field方法里的__init__属性,我们还可以改成attrs['table_name'] = class_name.lower(),这样我们输入的表名时就不会因为类名是大写,表名也只能大写了。
def insert(self, **kwargs):
		print(kwargs)

		# 循环去我们的字典中去拼接一个字段列表,一个值列表
		field_list = list()
		value_list = list()

		for key, value in kwargs.items():
			field_list.append(key)
			value_list.append(""" '%s' """ % str(value))  # 这个字符串里面加引号

		# 1 连接数据
		# 创建Connection连接
		conn = connect(host='localhost', port=3306, database='jing_dong', user='root', password='mysql', charset='utf8')
		# 获得Cursor对象
		cs1 = conn.cursor()

		# 2.执行sql语句
		sql = """ insert into %s(%s) values(%s); """ % (self.table_name, ",".join(field_list), ",".join(value_list))
		print(sql)
		cs1.execute(sql)

		# 提交
		conn.commit()

		# 3.关闭
		cs1.close()
		conn.close()

然后上面还有一个insert 的方法,其实作用都差不多,需要讲的一点就是,当你想在列表中加入单引号时,外面要包裹一对三引号。
def main():
	user = User()
	user.create_table()
	user.insert(age=100, name="oldyang")

	student = Student()
	student.create_table()
	student.insert(name="python11")

之后我们的创建表,修改,删除和添加字段就不用再写繁杂的SQL语句了。

你可能感兴趣的:(python)