class ModelMetaclass(type):
def __new__(cls, name,bases,attrs):
mappings = dict()
# 判断是否需要保存
for k,v in attrs.items():
# 判断是否是指定的 StringField 或者 IntegerField的实例对象
if isinstance(v,tuple):
# print('Found mapping: %s ==> %s'%(k,v))
mappings[k] = v
# 删除这些已经在字典中的属性
for k in mappings.keys():
attrs.pop(k)
# 将之前的uid/name/email/password 以及对应的对象引用、类名字
attrs['__mappings__'] = mappings # 保持属性和列的映射关系
attrs['__table__'] = name # 假设表名和类名一致
return type.__new__(cls,name,bases,attrs)
class User(metaclass=ModelMetaclass):
uid = ('uid',"int unsigned")
name = ('username',"varchar(30)")
email = ('email',"varchar(30)")
password = ('password',"varchard(30)")
# 当指定元类之后,以上的类属性将不在类中,而是在__mappings__属性指定的字典中存储
# 以上User类中有
# __mappings__ = {
# "uid": ('uid', "int unsigned")
# "name": ('username', "varchar(30)")
# "email": ('email', "varchar(30)")
# "password": ('password', "varchar(30)")
# }
# __table__ = "User"
def __init__(self,**kwargs):
for name,value in kwargs.items():
setattr(self,name,value)
def save(self):
field = []
args = []
for k,v in self.__mappings__.items():
field.append(v[0])
args.append(getattr(self,k,None))
sql = 'insert into %s (%s) values (%s)'%(self.__table__,','.join(field),','.join([str(i) for i in args]))
print("SQL: %s"%sql)
u = User(uid=12345, name='Michael', email='test@orm.org', password='my-pwd')
# print(u.__dict__)
u.save()