python数据库操作orm_python自定义ORM并操作数据库

import pymysql

'''

metaclass,直译为元类,简单的解释就是:

当我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。

但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。

连接起来就是:先定义metaclass,就可以创建类,最后创建实例。

所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。

当我们传入关键字参数metaclass时,魔术就生效了,它指示Python解释器在创建Student时,

要通过ModelMetaClass.__new__()来创建,在此,我们可以修改类的定义,比如,加上新的方法,然后,返回修改后的定义。

'''

class Field(object):#定义一个字段类

def __init__(self,name,column_type):

self.name = name#字段名

self.column_type = column_type#字段类型

def __str__(self):

return "<%s:%s>"%(self.name,self.column_type)

class StringField(Field):#字符串类型字段,继承Field

def __init__(self,name):

super(StringField,self).__init__(name,"varchar(100)")

# super(StringField, self).__init__(name,char(20))

class IntegerField(Field):#数字类型字段,继承Field

def __init__(self,name):

super(IntegerField,self).__init__(name,"int")

class ModelMetaClass(type):#定义一个元类

def __new__(cls, name,bases,attrs):

'''

:param name: 类的名称

:param bases: 类的继承

:param attrs: 类的属性

:return:

'''

if name == "Model":#如果传入的name:类名为Model则不进行操作,直接返回type类的相关参数

return type.__new__(cls,name,bases,attrs)

# return super(ModelMetaClass, self).__new__(cls,name,bases,attrs)

print('Found model: %s' % name) # 打印当前实例的类名称

mapping = dict() #空字典

for k,v in attrs.items(): #遍历属性

print('key:%s,value:%s' % (k, v))#打印遍历attrs的key和value

if isinstance(v,Field): #判断属性是否Field的实例

mapping[k] = v #添加到mapping当中

# print(mapping)

for k in mapping.keys(): #返回所有键

attrs.pop(k) #mapping里存在的内容从属性当中删除

attrs["__mapping__"] = mapping #设定__mapping__属性来保存字段

attrs["__table__"] = name #设定类名和表名一致(不区分大小写)

# print(attrs)

return type.__new__(cls,name,bases,attrs)#返回给类实例,这里为Student

class Model(dict,metaclass = ModelMetaClass):#创建一个实例类,设置其元类

def __init__(self,**kwargs):

self.db = pymysql.connect(#链接数据库

host = "localhost",

user = "root",

password = "123",

database = "test"

)

self.cursor = self.db.cursor()

super(Model,self).__init__(**kwargs)

def __getattr__(self, key):

return self[key]#返回对象的属性值

# print(self[key])

def __setattr__(self, key, value):

self[key] = value#设置对象的属性及其对应的值

def save(self):

fields = [] #空列表用来存储字段

args = [] #空列表用来存储字段的值

for k,v in self.__mapping__.items():

fields.append(v.name)#此时,v为field子类的实例,因此可以取出类属性name,作为字段名

# print(getattr(self, k, None))

args.append(getattr(self,k,None))#此时调用了self,则将传入的参数调用,此时再取变量的值,则为传入的实参

sql = "insert into %s(%s) values (%s)"%(

self.__table__,

",".join(fields),

",".join([repr(str(i)) for i in args]

)) #sql拼接

self.cursor.execute(sql)

print(sql)

def __del__(self):

'''

回收内存

'''

self.db.commit()

self.cursor.close()

self.db.close()

class Student(Model):#model实例类的子类

name = StringField("name")

# print(name)

room_id = IntegerField("room_id")

# print(room_id)

u = Student(name = "张3",room_id = 6)#实质是创建了一个字典的对象

u.save()#调用父类的save方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值