[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 ...
随机推荐
- PAT B1048 数字加密 (20)
AC代码 #include <cstdio> #include <cstring> #include <algorithm> #include <iostre ...
- [POI2012]ROZ-Fibonacci Representation (贪心)
大意: 给定数$n$, 求将$n$划分为最少的斐波那契数的和或差. 每次取相邻$n$的斐波那契数一定最优, 考虑证明. 结论1:存在一个最优解,使得每个斐波那契数使用不超过1次.(考虑$2F_n=F_ ...
- 怎样在 Vue 中使用 v-model 实现双向数据绑定?
1. 所谓 双向数据绑定, 可以理解为: 修改 A , B 会跟着被修改, 修改 B , A 会跟着被修改. 常用在需要 进行用户输入的地方, 比如 这些 html 标签: input.select ...
- 【原创】大叔经验分享(58)kudu写入压力大时报错
kudu写入压力大时报错 19/05/18 16:53:12 INFO AsyncKuduClient: Invalidating location fd52e4f930bc45458a8f29ed1 ...
- webpack抽取CSS文件与CSSTreeShaking
webpack抽取CSS文件 CSSTreeShaking 一.webpack抽取CSS文件 抽取CSS文件的插件:mini-css-extract-plugin npm install --save ...
- Ajax与JSON,XML,PHP
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js jquery 动态添加表格
for循环将你要添加的标签写上,然后直接var talbeAdd=""for(){ tableAdd+="<tr><td>这儿写你要添加的内容&l ...
- C#中构建多线程应用程序[转]
原文:http://blog.sina.com.cn/s/blog_4e61c4290100ndyl.html C#中构建多线程应用程序[转] (2011-01-04 21:29:29) 转载▼ 标签 ...
- Tensorflow模型代码调试问题
背景: 不知道大家有没有这样的烦恼:在使用Tensorflow搭建好模型调试的过程中,经常会碰到一些问题,当时花了不少时间把这个问题解决了,一段时间后,又出现了同样的问题,却怎么也不记得之前是怎么解决 ...
- 用Python+Aria2写一个自动选择最优下载方式的E站爬虫
前言 E站爬虫在网上已经有很多了,但多数都只能以图片为单位下载,且偶尔会遇到图片加载失败的情况:熟悉E站的朋友们应该知道,E站许多资源都是有提供BT种子的,而且通常打包的是比默认看图模式更高清的文件: ...