[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 ...
随机推荐
- 【NOIP2015普及组】 推销员(纪中数据-标准)
题目 [题目描述] 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家住户,第 i 家住户到入口的距离为 ...
- Yii2.0 queue
https://www.yiichina.com/tutorial/1635 https://my.oschina.net/gcdong/blog/3031113 https://www.yii-ch ...
- Linux目录结构解释
Linux的常用命令 cp: 用于文件复制的命令. cp file_1 file_2 copy_position -v: 复制的详细过程. -r: 复制目录. mv: 文件移动或文件重命名. mv f ...
- Git 学习笔记之(三)将本地工程导入到GitHub 仓库中
一:操作步骤第一步:建立git仓库 cd到你的本地项目根目录下,执行git命令,此命令会在当前目录下创建一个.git文件夹. git init 第二步:将项目的所有文件添加到仓库中 git add . ...
- 关于C++内存对齐
关于C++内存对齐 C++11从标准层面引入了一些和内存对齐相关的特性,标准库也增加了对应的组件,这里稍微总结一下. 取得某个类型的对齐值 C++中的Object(对象)是指一块满足以下条件的内存区域 ...
- centos7 开放/关闭防火墙和端口
--------------------------------------------------------------防火墙----------------------------------- ...
- 阿里云linux配置ftp服务
阿里云linux配置ftp服务 一.ftp服务安装 运行以下命令安装ftp yum install -y vsftpd 运行以下命令打开及查看etc/vsftpd cd /etc/vsftpd ls ...
- 使用ViewFlipper实现图片轮播
public class MainActivity extends AppCompatActivity { private ViewFlipper flipper; //背景图片int[] id pr ...
- C++第二次作业--函数
1.为什么要用函数 创建 C++ 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务.通过函数我们可以实现代码复用,即可以重复使用和在各种适用情况下使用,函数的存在增强了程序的可读性.并且函 ...
- springboot自动装备date类型报错问题
错误消息: Field error in object 'user' on field 'birthday': rejected value [2001-02-14]; codes [typeMism ...