ORM

  • 对象关系映射 Object Relational Mapping

    • 表 ---> 类
    • 字段 ---> 属性
    • 记录 ---> 对象
# mysql_client.py

import pymysql

class MySQLClient:

    def __init__(self):
# 建立连接
self.client = pymysql.connect(
host='localhost',
port=3306,
user='root',
password='123',
database='orm_demo',
charset='utf8',
autocommit=True
) # 获取游标
self.cursor = self.client.cursor(
pymysql.cursors.DictCursor
) # 提交查询sql语句并返回结果
def my_select(self, sql, value=None):
print('sql:', sql, '\nvalue:', value)
self.cursor.execute(sql, value)
res = self.cursor.fetchall()
return res # 提交增加, 修改的sql语句
def my_execute(self, sql, values):
try:
print('<sql>:', sql, '\n<values>:', values)
self.cursor.execute(sql, values)
except Exception as e:
print(e) # 关闭连接
def close(self):
self.cursor.close()
self.client.close()
# ORM.py
from mysql_client import MySQLClient # 定义字段类
class Field:
def __init__(self, name, column_type, primary_key, default):
self.name = name
self.column_type = column_type
self.primary_key = primary_key
self.default = default # 定义整数字段类
class IntegerField(Field):
def __init__(self, name, column_type='int', primary_key=False, default=0):
super().__init__(name, column_type, primary_key, default) # 定义字符字段类
class StringField(Field):
def __init__(self, name, column_type='varchar(64)', primary_key=False, default=''):
super().__init__(name, column_type, primary_key, default) # 定义元类
class OrmMetaClass(type):
def __new__(cls, class_name, class_bases, class_dict): if class_name == 'Models':
return super().__new__(cls, class_name, class_bases, class_dict) # 没有表名则默认等于类名
table_name = class_dict.get('table_name', class_name) primary_key = None # 定义一个空字典, 用来存放字段对象
mappings = {} for key, value in class_dict.items():
# 筛选字段对象
if isinstance(value, Field):
mappings[key] = value if value.primary_key:
if primary_key:
raise TypeError('只能有一个主键!') primary_key = value.name if not primary_key:
raise TypeError('必须有一个主键!') # 删除class_dict中和mappings重复的字段属性
for key in mappings.keys():
class_dict.pop(key) # 将表名添加到class_dict中
class_dict['table_name'] = table_name
# 将主键添加到class_dict中
class_dict['primary_key'] = primary_key
# 将mappings添加到class_dict中
class_dict['mappings'] = mappings return super().__new__(cls, class_name, class_bases, class_dict) # 定义Models类
class Models(dict, metaclass=OrmMetaClass):
def __getattr__(self, item):
return self.get(item) def __setattr__(self, key, value):
self[key] = value # 查询
@classmethod
def orm_select(cls, **kwargs): # kwargs --> {'id': 1} mysql = MySQLClient() # select * from User
if not kwargs:
sql = 'select * from %s' % cls.table_name res = mysql.my_select(sql) else:
key = list(kwargs.keys())[0]
value = kwargs.get(key) sql = 'select * from %s where %s=?' % (cls.table_name, key) sql = sql.replace('?', '%s') res = mysql.my_select(sql, value) mysql.close() # 返回的是[{}]一个普通的字典(在列表内), 我们把这个字典传入Models类, 让其可以 "对象.属性"
return [cls(**d) for d in res] # d是一个字典 # 增加
def orm_insert(self):
mysql = MySQLClient() # 存字段名
keys = []
# 存字段值
values = []
# 存 "?"
args = [] for k, v in self.mappings.items():
# 过滤主键, 因为主键是自增的
if not v.primary_key:
# 字段名
keys.append(v.name) # 字段值, 没有值则使用默认值
values.append(
getattr(self, v.name, v.default)
) # 有几个字段就存放几个"?"
args.append('?') sql = 'insert into %s (%s) values (%s)' % (
self.table_name,
','.join(keys),
','.join(args)
) sql = sql.replace('?', '%s')
print(sql)
print(values) mysql.my_execute(sql, values)
mysql.close() # 修改
def orm_update(self):
mysql = MySQLClient() # 存字段名
keys = []
# 存字段值
values = []
# 主键值
primary_key = None for k, v in self.mappings.items():
if v.primary_key:
# 获取主键值
primary_key = v.name + '= %s' % getattr(self, v.name) else:
keys.append(v.name + '=?')
values.append(
getattr(self, v.name)
) sql = 'update %s set %s where %s' % (
self.table_name,
','.join(keys),
primary_key
) # sql: update table set k1=%s, k2=%s where id=pk
sql = sql.replace('?', '%s') mysql.my_execute(sql, values)
mysql.close() # 定义用户类
class User(Models):
user_id = IntegerField('user_id', primary_key=True)
user_name = StringField('user_name')
password = StringField('password') user_obj = User.orm_select(user_id=1)[0] # 查询
print(user_obj) # {'user_id': 1, 'user_name': 'blake', 'password': '123'}
user_obj.user_name = 'bigb' # 修改user_name
user_obj.orm_update() # 将修改提交到数据库

Python 3 对象关系映射(ORM)的更多相关文章

  1. Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包

    Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...

  2. 对象关系映射ORM

    对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效 ...

  3. Django 源码小剖: Django 对象关系映射(ORM)

    引 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django O ...

  4. 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

    通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...

  5. 对象-关系映射ORM(Object Relational Mapping)(转)

    ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现 Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件 ...

  6. 对象关系映射 ORM

    1.1 作用 MTV框架中包括一个重要的部分,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因 ...

  7. 对象关系映射(ORM)框架GreenDao简介和基本使用

    官网上的介绍,greenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案. GreenDao特点 性能最大化,可能是Android平台上最快的ORM框架 易于使用的A ...

  8. Python学习---django之ORM语法[对象关系映射]180124

    ORM语法[对象关系映射] ORM: 用面向对象的方式去操作数据库的创建表以及增删改查等操作. 优点:1 ORM使得我们的通用数据库交互变得简单易行,而且完全不用考虑该死的SQL语句.快速开发. 2 ...

  9. 对象关系映射(ORM)

    1.什么是 对象-关系映射 对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,OR ...

随机推荐

  1. java编程思想第四版第十八章总结

    一.概述 如何学习java I/O 学习I/O类库 学习I/O发展史,为什么要学习发展史呢? 因为,如果缺乏发展史,我们就会对什么时候使用哪个类,以及什么时候不该使用它们而感到迷惑. 了解nio 二. ...

  2. Django 通过 ORM 实现表的CRUD

    Django 通过 ORM 实现表的CRUD 单表的创建 修改 setting.py 文件 DATABASES = { 'default': { 'ENGINE': 'django.db.backen ...

  3. nyoj 773-开方数 (pow)

    773-开方数 内存限制:64MB 时间限制:1000ms 特判: No 通过数:3 提交数:8 难度:3 题目描述: 现在给你两个数 n 和 p ,让你求出 p 的开 n 次方. 输入描述: 每组数 ...

  4. 力扣(LeetCode)从不订购的客户-数据库题 个人题解

    SQL架构 某网站包含两个表,Customers 表和 Orders 表.编写一个 SQL 查询,找出所有从不订购任何东西的客户. Customers 表: +----+-------+ | Id | ...

  5. lldb调试使用python脚本问题总结

    lldb调试器可以使用python脚本实现功能增强,但也不是可以随心所欲的,在实际中有很多地方需要注意. 首先是对多线程环境调试使用python脚本,也要考虑python脚本有多线程安全,尤其是有许多 ...

  6. PHP中的服务容器与依赖注入的思想

    依赖注入 当A类需要依赖于B类,也就是说需要在A类中实例化B类的对象来使用时候,如果B类中的功能发生改变,也会导致A类中使用B类的地方也要跟着修改,导致A类与B类高耦合.这个时候解决方式是,A类应该去 ...

  7. 【NHOI2018】扫雷完成图

    [题目描述] 扫雷游戏完成后会显示一幅图,图中标示了每个格子的地雷情况.现在,一个 n * n 方阵中有 k 个地雷,请你输出它的扫雷完成图. [输入数据] 输入共 k+1 行: 第 1 行为 2 个 ...

  8. linux计算机网络基础

    OSI7层协议和TCP/IP4层网络协议 第一层:物理层,定义各种物理设备的规范,如通信距离,接口大小等. 第二层:数据链路层,基于mac地址通信是,数据报文封装和相应方式. 第三层:网络层,基于IP ...

  9. Maven设置http代理

    背景:有时候公司处于安全因素的考虑,需要通过代理访问因特网,这种情况需要为Maven设置htpp代理 设置步骤如下: 1 首先确认自己无法访问外网公共的中央仓库(可通过ping repo1.maven ...

  10. 实战webpack系列03

    03.Webpack的强大功能 一.生成Source Maps(使调试更容易) 通过简单的配置,webpack就可以在打包时为我们生成的source maps,这为我们提供了一种对应编译文件和源文件的 ...