only网站建设分析,深圳做网站多少钱,北京网站设计方案,校园官方网站如何制作1. ORM是什么
ORM 是 python编程语言后端web框架 Django的核心思想#xff0c;“Object Relational Mapping”#xff0c;即对象-关系映射#xff0c;简称ORM。
一个句话理解就是#xff1a;创建一个实例对象#xff0c;用创建它的类名当做数据表名#xff0c;用创建它…1. ORM是什么
ORM 是 python编程语言后端web框架 Django的核心思想“Object Relational Mapping”即对象-关系映射简称ORM。
一个句话理解就是创建一个实例对象用创建它的类名当做数据表名用创建它的类属性对应数据表的字段当对这个实例对象操作时能够对应MySQL语句 demo:
class User(父类省略):uid (uid, int unsigned)name (username, varchar(30))email (email, varchar(30))password (password, varchar(30))...省略...u User(uid12345, nameMichael, emailtestorm.org, passwordmy-pwd)
u.save()
# 对应如下sql语句
# insert into User (username,email,password,uid)
# values (Michael,testorm.org,my-pwd,12345)说明
所谓的ORM就是让开发者在操作数据库的时候能够像操作对象时通过xxxx.属性yyyy一样简单这是开发ORM的初衷只不过ORM的实现较为复杂Django中已经实现了 很复杂的操作本节知识 主要通过完成一个 insert相类似的ORM理解其中的道理就就可以了
2. 通过元类简单实现ORM中的insert功能
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(metaclassModelMetaclass):uid (uid, int unsigned)name (username, varchar(30))email (email, varchar(30))password (password, varchar(30))# 当指定元类之后以上的类属性将不在类中而是在__mappings__属性指定的字典中存储# 以上User类中有 # __mappings__ {# uid: (uid, int unsigned)# name: (username, varchar(30))# email: (email, varchar(30))# password: (password, varchar(30))# }# __table__ Userdef __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields []args []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, None))sql insert into %s (%s) values (%s) % (self.__table__, ,.join(fields), ,.join([str(i) for i in args]))print(SQL: %s % sql)u User(uid12345, nameMichael, emailtestorm.org, passwordmy-pwd)
# print(u.__dict__)
u.save()执行的效果:
Found mapping: password (password, varchar(30))
Found mapping: email (email, varchar(30))
Found mapping: uid (uid, int unsigned)
Found mapping: name (username, varchar(30))
SQL: insert into User (uid,password,username,email) values (12345,my-pwd,Michael,testorm.org)3. 完善对数据类型的检测
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(metaclassModelMetaclass):uid (uid, int unsigned)name (username, varchar(30))email (email, varchar(30))password (password, varchar(30))# 当指定元类之后以上的类属性将不在类中而是在__mappings__属性指定的字典中存储# 以上User类中有 # __mappings__ {# uid: (uid, int unsigned)# name: (username, varchar(30))# email: (email, varchar(30))# password: (password, varchar(30))# }# __table__ Userdef __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields []args []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, 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 insert into %s (%s) values (%s) % (self.__table__, ,.join(fields), ,.join(args_temp))print(SQL: %s % sql)u User(uid12345, nameMichael, emailtestorm.org, passwordmy-pwd)
# print(u.__dict__)
u.save()运行效果如下:
Found mapping: uid (uid, int unsigned)
Found mapping: password (password, varchar(30))
Found mapping: name (username, varchar(30))
Found mapping: email (email, varchar(30))
SQL: insert into User (email,uid,password,username) values (testorm.org,12345,my-pwd,Michael)4. 抽取到基类中
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 Model(object, metaclassModelMetaclass):def __init__(self, **kwargs):for name, value in kwargs.items():setattr(self, name, value)def save(self):fields []args []for k, v in self.__mappings__.items():fields.append(v[0])args.append(getattr(self, k, 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 insert into %s (%s) values (%s) % (self.__table__, ,.join(fields), ,.join(args_temp))print(SQL: %s % sql)class User(Model):uid (uid, int unsigned)name (username, varchar(30))email (email, varchar(30))password (password, varchar(30))u User(uid12345, nameMichael, emailtestorm.org, passwordmy-pwd)
# print(u.__dict__)
u.save()