[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 ...
随机推荐
- 将本地镜像上传到Docker镜像仓库
⒈在Docker Hub(Docker官方镜像仓库)注册自己的用户名. ⒉在Docker中使用docker login命令登录自己的用户名密码. ⒊使用docker push 镜像名称 上传本地镜像到 ...
- PAT A1025 PAT Ranking(25)
题目描述 Programming Ability Test (PAT) is organized by the College of Computer Science and Technology o ...
- django CBV装饰器 自定义django中间件 csrf跨站请求伪造 auth认证模块
CBV加装饰器 第一种 @method_decorator(装饰器) 加在get上 第二种 @method_decorator(login_auth,name='get') 加在类上 第三种 @met ...
- Java实现的基础数据结构
Java实现的基础数据结构 0,常用的基础数据结构 图1 基础数据结构&相关特性 图2 Java自带的类集框架&继承关系图 1,数组[Array] 特点:长度固定.查找方便[直接使用i ...
- ModbusTCP报文详解【二】
[1]功能码05H [2]功能码06H [3]功能码0FH [4]功能码10H
- 【原创】运维基础之Amplify
官方:https://www.nginx.com/products/nginx-amplify/ NGINX Amplify is a SaaS‑based monitoring tool for t ...
- O043、计算节点宕机了怎么办
参考https://www.cnblogs.com/CloudMan6/p/5562131.html Rebuild 可以恢复损坏的instance .那如果是宿主机坏了怎么办呢?比如硬件故障或者 ...
- element-ui select
1. 组合 label <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...
- Java反射【一、概述】
.net也使用过反射,不过用的比较浅显,用来记日志等.. Java基础课程学习已经过了一段时间了,接下来继续学习 本次学习包含以下内容 Java反射[一.概述] Java反射[二.Class类的使用] ...
- TCP超时与重传
TCP提供可靠的传输层.它使用的方法之一就是确认从另一端收到的数据.但数据和确认都有可能丢失.TCP通过在发送时设置一个定时器来解决这种问题.如果当定时器溢出时还没收到确认,他就重传数该数据.对任何实 ...