[Python之路] ORM(对象关系映射)
一、概念
ORM是Python后端Web框架Django的核心思想,"Object Relational Mapping",即对象-关系映射,简称ORM。
一句话理解就是:
创建一个实例对象,用创建它的类名当做数据表名,用创建它的类属性对应数据表的字段,当对这个实例对象操作时,能够对应MySQL语句。
也就是说,当我们定义了User类,就相当于在数据库中创建了User表。我们使用User类创建一个实例对象,就相当于往表中插入一跳数据。
u = User(uid=123, name="leo", email="leo@163.com", password="")
u.save()
二、ORM的简易实现
# 定义一个元类(继承于type),用于创建User类
class ModelMetaClass(type):
def __new__(cls, name, bases, attrs):
mappings = dict()
for k, v in attrs.items():
if isinstance(v, tuple):
print("Found mapping: %s ==> %s" % (k, v))
mappings[k] = v for k in mappings.keys():
attrs.pop(k) # 将attrs中的属性转化为以下形式
attrs['__mappings__'] = mappings
attrs['__table__'] = name return type.__new__(cls, name, bases, attrs) # 用户定义User类
class User(metaclass=ModelMetaClass):
# 用户定义的属性,在元类调用__new__时,会将属性进行变形(如下注释部分代码)
uid = ('uid', 'int unsigned')
name = ('name', 'varchar(30)')
email = ('email', 'varchar(30)')
password = ('password', 'varchar(30)') # 上述属性变形为以下形式
# __mappings__ = {
# "uid": ('uid', 'int unsigned'),
# "name": ('name', '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) # 调用save,则相当于执行sql语句
def save(self):
fields = []
args = []
for k, v in self.__mappings__.items():
# 获取所有字段名
fields.append(v[0])
# 获取字段名对应的值
args.append(getattr(self, k, None)) # 给args中的值,如果不是数字,则需要加上引号(SQL中需要加引号,这里加单引号)
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
sql = """insert into %s (%s) values (%s)""" % (self.__table__, ','.join(fields), ','.join(args_temp))
print('SQL: %s' % sql) u = User(uid=1234, name="Leo", email="leo001@163.com", password="")
u.save()
如上述代码,我们通过元类的__new__实现了简易的对象-关系映射。Django中的ORM实现要复杂得多,但从这里可以看出一些基本的思想。
我们如果要定义多个表的话,我们可以将构造函数和save方法都抽象到父类里面去:
# 定义一个元类(继承于type),用于创建User类
class ModelMetaClass(type):
def __new__(cls, name, bases, attrs):
mappings = dict()
for k, v in attrs.items():
if isinstance(v, tuple):
print("Found mapping: %s ==> %s" % (k, v))
mappings[k] = v for k in mappings.keys():
attrs.pop(k) # 将attrs中的属性转化为以下形式
attrs['__mappings__'] = mappings
attrs['__table__'] = name return type.__new__(cls, name, bases, attrs) class Model(object, metaclass=ModelMetaClass):
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中的值,如果不是数字,则需要加上引号(SQL中需要加引号,这里加单引号)
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
sql = """insert into %s (%s) values (%s)""" % (self.__table__, ','.join(fields), ','.join(args_temp))
print('SQL: %s' % sql) # 用户定义User类,继承于Model父类,如果这里没有制定MetaClass,则会到父类去找
class User(Model):
# 用户定义的属性,在元类调用__new__时,会将属性进行变形(如下注释部分代码)
uid = ('uid', 'int unsigned')
name = ('name', 'varchar(30)')
email = ('email', 'varchar(30)')
password = ('password', 'varchar(30)') # 上述属性变形为以下形式
# __mappings__ = {
# "uid": ('uid', 'int unsigned'),
# "name": ('name', 'varchar(30)'),
# "email": ('email', 'varchar(30)'),
# "password": ('password', 'varchar(30)')
# }
# __table__ = "User" u1 = User(uid=1234, name="Leo", email="leo001@163.com", password="")
u1.save() u2 = User(uid=1235, name="Jone", email="Jone@163.com", password="")
u2.save()
[Python之路] ORM(对象关系映射)的更多相关文章
- Django---静态文件配置,post提交表单的csrf问题(日后细说),创建app子项目和分析其目录,ORM对象关系映射简介,Django操作orm(重点)
Django---静态文件配置,post提交表单的csrf问题(日后细说),创建app子项目和分析其目录,ORM对象关系映射简介,Django操作orm(重点) 一丶Django的静态文件配置 #we ...
- ORM 对象关系映射
ORM (object relation mapping) 就是将对象数据转换为sql语句并执行 对象关系映射框架 orm 需要做的事情 1 生成创建表的语句 2 插入数据的语句 3 删除数据的语句 ...
- Php ORM 对象关系映射
ORM的全称是Object Relational Mapping,即对象关系映射.它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将 ...
- $Django setting.py配置 ,GET、POST深入理解,三件套,orm对象关系映射简介
1 django中app的概念: 大学:----------------- 项目 信息学院 ----------app01 物理学院-----------app02 ****强调***:创建的每一 ...
- ORM对象关系映射
ORM 总结: ORM:对象关系映射 作用: 1.将定义数据库模型类--> 数据库表 2.将定义数据库模型类中的属性--->数据库表字段 3.将模型对象的操作(add,delete,com ...
- Java 自定义注解实现ORM对象关系映射
一,ORM概念 ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关 ...
- django-模型之(ORM)对象关系映射(一)
所谓对象关系映射,就是将数据库的一些名字与python中的一些名字相对应,表名-->类名,字段-->属性,操作(增删改查)-->方法.这样,我们就可以通过对Python代码的编辑来对 ...
- ORM对象关系映射之GreenDAO源码解析
上一篇我们学习了GreenDAO的CRUD基本操作,可以说是非常的方便的,而且GreenDAO的效率和性能远远高于其它两款流行的ORM框架,下面是我从官网找的一副它们三个ORM框架之间的性能测试的直观 ...
- Python Web框架篇:Django Model ORM(对象关系映射)
一,基本操作 用于实现面向对象编程语言里不同类型系统的数据之间的转换,换言之,就是用面向对象的方式去操作数据库的创建表以及增删改查等操作. 1.增(create , save): from app01 ...
- ORM对象关系映射:
django配置orm: django使用mysql数据库: 首先cmd创建库 settings配置mysql数据库: DATABASES = { 'default': { 'ENGINE': 'dj ...
随机推荐
- Lucky Sorting(CodeForces-109D)【思维】
题意:给出一组数,要求从小到大排序,并且排序的过程中,发生交换的两个数至少一个为幸运数(十进制位均为4或7),问能否在(2×n)次交换内完成排序,如果能,输出交换的方案(不要求步骤数最少). 思路:首 ...
- package[golang]学习笔记之context
*关于context https://talks.golang.org/2014/gotham-context.slide#29
- MySQL安装及初级增删改查一
学习MYsql 是参照这个维C果糖的总结,学习目录网址:https://blog.csdn.net/qq_35246620/article/details/70823903,谢谢大神的无私分享. 一. ...
- ZOOKEEPER之WATCHER简介
zookeeper通过watcher机制,可以实现数据的修改,删除等情况的监听 可以设置观察的操作:exists,getChildren,getData 可以触发观察的操作:create,delete ...
- C#文本转换为Json格式
private string ConvertJsonString(string str) { //格式化json字符串 JsonSeriali ...
- 分库分布的几件小事(四)分库分表的id主键生成
1.问题 其实这是分库分表之后你必然要面对的一个问题,就是id咋生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定不对啊,需要一个全局唯一的id来支持.所以这都是你实际生产环境中必须考虑的问 ...
- global.css
global.css /* 页面元素初始化和常用样式定义-start */ /*======== 全局 ========*/ body, div, dl, dt, dd, ul, ol, li, h1 ...
- powershell查看版本信息
在终端输入$PSVersionTable
- easyui-datagrid 编辑模式详解——combobox
用于列表显示号了,需要改动某一列的值,而且根据每一行的数据去加载data数据,放在这个列中供别人选择 //-------------------- 代码可变区//---------- 数据定义区var ...
- 分布式缓存Redis+Memcached经典面试题和答案
Redis相比memcached有哪些优势? (1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) redis的速度比memcached快很多 ( ...