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. nyoj 290 动物统计加强版 (字典树 (Trie) PS:map<TLE>)

    动物统计加强版 时间限制:3000 ms  |  内存限制:150000 KB 难度:4   描述 在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物资料中有未统计数量的原始动物的名单 ...

  2. 自制反汇编逆向分析工具 与hopper逆向输出对比

    经过一个阶段5次迭代之后,本逆向分析工具功能基本成形.工具的基本功能介绍请参看前面的posts. 现在就和hopper的逆向函数伪代码的功能对比一下效果.在这里并非定胜劣,因为差异可以拿来对比参照,通 ...

  3. 18个awk的经典实战案例

    介绍 这些案例是我收集起来的,大多都是我自己遇到过的,有些比较经典,有些比较具有代表性. 这些awk案例我也录了相关视频的讲解awk 18个经典实战案例精讲,欢迎大家去瞅瞅. 插入几个新字段 在&qu ...

  4. 新闻实时分析系统 基于IDEA环境下的Spark2.X程序开发

    1.Windows开发环境配置与安装 下载IDEA并安装,可以百度一下免费文档. 2.IDEA Maven工程创建与配置 1)配置maven 2)新建Project项目 3)选择maven骨架 4)创 ...

  5. 图解 Spring:HTTP 请求的处理流程与机制【4】

    4. HTTP 请求在 Spring 框架中的处理流程 在穿越了 Web 容器和 Web 应用之后,HTTP 请求将被投送到 Spring 框架,我们继续剖析后续流程.Web 应用与 Spring M ...

  6. 一个HTML5培训班毕业生的找工作随笔

    昨天刚参加完一个面试,通过了.写个随笔记录一下. 先介绍一下背景. 我是今年十月份的时候从某个培训机构的HTML5 Web前端培训班毕业的,是一个刚进入IT行业的新人. 本人毕业于某三流学校,在参加培 ...

  7. selenium处理隐藏元素的方法

    <li class="navbar-nav-item ">       <a href="#" id="cust"> ...

  8. django-migrate一败再败

    python3 manage.py makemigrations # 生成数据库迁移文件 python3 manage.py migrate # 迁移数据库 简简单单两条命令就完成了django的数据 ...

  9. 二进制安装 k8s 1.15.6 集群

    目录: 第一篇 环境介绍与基础配置 第二篇 部署前期准备工作 第三篇 ETCD 集群部署 第四篇 master节点的部署介绍和前置工作 第五篇 kube-nginx 和 keepalived 部署安装 ...

  10. iOS 一些struct类型的NSLog输出格式

    https://my.oschina.net/sayonala/blog/215910 我们经常会输出一些坐标尺寸信息之类的,比如view的frame,是CGRect类型的,用frame.oringi ...