初识orm

一、什么是orm

  • 介绍
ORM: 对象关系映射
将随对象映射成 数据表中的鱼跳跳记录 类--->表名
对象--->记录
对象.属性--->字段 # 演示映射关系
'''
User table:名字、年龄、性别 class User
user_obj = User()
user_obj.name属性
user_obj.age 属性 '''
  • 演示orm以及自定义元类
# 定义字段类型:每个字段都应该有---> 字段名、字段类型、是否为主键、默认值
# 字段父类
#
# 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
#
#
# # varchar
# class StringField(Field):
# def __init__(self, name, column_type='varchar(64)', primary_key=False, default=None):
#
# super().__init__(name, column_type, primary_key, default)
#
#
#
#
# # int
# class IntegerField(Field):
# def __init__(self, name, column_type='int', primary_key=False, default=0):
# super().__init__(name, column_type, primary_key, default)
#
#
# #自定义元类
# '''
# 解决了三件事:
# 1、保证一张表必须要有表名
# 2、保证一张表中只能有一个主键
# 3、将所有“字段名” 与 “字段对象” 添加到一个独立的字典中(mappings)
# 以 key(字段名):values(字段对象),添加到类的名称空间中,方便后期使用
# '''
#
# class OrmMetaClass(type):
#
# # def __new__(cls, *args, **kwargs):
# # class_name, class_bases, class_attr = args
# # print(f'类名:{class_name}')
# # print(f'基类:{class_bases}')
# # print(f'类的名称空间:{class_attr}')
# def __new__(cls, class_name, class_bases, class_attr):
#
# # 1、过滤Models类
#
#
#
#
#
#
#
#
# class Models(dict, metaclass=OrmMetaClass):
#
# # 对象.属性 没有时触发
# def __getattr__(self, item):
#
# return self.get(item) # # {'name': 'tank', 'pwd': '123'}.get('name')
#
# # 对象.属性 = 属性值 时触发
# def __setattr__(self, key, value):
#
# # 给字典添加键值对的方式
# self[key] = value
#
#
#
#
# # User 用户名 密码
# class User(Models):
#
# # 用户自定义,表名为 user_info
# # table_name = 'user_info'
# #
# # obj = IntegerField(name='id', primary_key=True)
# # print(obj.primary_key)
# # print(obj.name)
# # print(obj.default)
#
# # IntegerField字段类中的name属性 必须与User表中类属性同名
# id = IntegerField(name='id', primary_key=True)
# username = StringField(name='username')
# password = StringField(name='password') #
# if __name__ == '__main__':
# user_dic = dict({'name': 'tank', 'pwd': '123'})
#
# print(type(user_dic))
#
#
# user_obj = User(naem='tank', pwd='123')
# # print(user_obj)
# # print(user_obj.__dict__)
# # 问题1 通过对象.属性 的方式无法获取属性值 只能通过字典的取值方式获取 因为继承的是dict字典类
# # print(user_obj.name)
# # print(user_obj.get('name'))
# # print(user_obj['name'])
# # print(type(user_obj))
#
# # 问题2:继续的字典无法通过 对象.属性的 取值方式 , 对象.属性 = 属性值 增加或修改属性的操作
# # 解决2: __getattr__解决了取值方式,__setattr__解决了增加或修改属性的方式
# # print(user_obj.name)
#
# print(user_obj.__dict__)
# print('添加属性前:--->', user_obj)
#
#
# # User 类实例化出来的 user_obj 普通对象 添加属性的方式
# user_obj.user_type = 'admin'
# print(user_obj.__dict__)
#
# print('添加属性后:--->', user_obj) 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 # varchar
class StringField(Field):
def __init__(self, name, column_type='varchar(64)', primary_key=False, default=None):
super().__init__(name, column_type, primary_key, default) # int
class IntegerField(Field):
def __init__(self, name, column_type='int', primary_key=False, default=0):
super().__init__(name, column_type, primary_key, default) # 自定义元类
'''
解决了三件事:
1、保证一张表必须要有表名
2、保证一张表中只能有一个主键
3、将所有“字段名” 与 “字段对象” 添加到一个独立的字典中(mappings)
以 key(字段名):values(字段对象),添加到类的名称空间中,方便后期使用
''' from mysql_control import MySQL class OrmMetaClass(type): # def __new__(cls, *args, **kwargs):
# class_name, class_bases, class_attr = args
# print(f'类名:{class_name}')
# print(f'基类:{class_bases}')
# print(f'类的名称空间:{class_attr}')
def __new__(cls, class_name, class_bases, class_attr): # 1、过滤Models类
if class_name == 'Models':
# 将models类的类名,基类,名称空间原路返回
return type.__new__(cls, class_name, class_bases, class_attr) # 2、获取 table 表名 ,若自定义则获取自定义的表名,没有则默认使用类名做表名
# dict.get(key) ---> key若有则返回对应的值,若没有则返回默认追 class_name 就是默认值
table_name = class_attr.get('table_name', class_name)
# print(table_name) # 主键值:主键名为:字段名,比如主键是 id字段 ---> id就是主键的名字
primary_key = None # 存放字段名与字段对象的字典
mappings = {} # 3、保证一张表只能有唯一的一个主键
# 循环遍历类的名字
for k, v in class_attr.items():
# print(k, v)
# 将字段以外的属性过滤掉
# 判断当前的v是否是字段对象
if isinstance(v, Field):
# print(k, v)
# print(v.__dict__)
# 4、将所有 “字段名” 与 “字段对象” 添加到一个独立的字典中(mappings)
mappings[k] = v # 坑
# class_attr.pop(k) # 纠正 ,这里当字典被迭代时,不能直接修改其属性 # 判断字段对象 如果有 主键primary_key, 则为primary_key 变量赋值
if v.primary_key:
# 若第二次进来,primary_key 有值,证明有主键 ,抛出异常
if primary_key:
raise TypeError('一张表只能有一个主键') # primary_key = k
# 给primary_key变量做一个赋值操作
primary_key = v.name # 5、过滤掉类名称空间中重复的字段属性
for key in mappings.keys():
class_attr.pop(key) # print(table_name)
# print(mappings)
# print(class_attr) if not primary_key:
raise TypeError('必须要有一个主键!!!') # 6、给类的名称空间,添加table_name, primary_key, mappings属性
class_attr['table_name'] = table_name
class_attr['primary_key'] = primary_key
class_attr['mappings'] = mappings # print('*' * 100)
# print(class_attr) return type.__new__(cls, class_name, class_bases, class_attr) class Models(dict, metaclass=OrmMetaClass): # 对象.属性 没有时触发
def __getattr__(self, item):
return self.get(item) # # {'name': 'tank', 'pwd': '123'}.get('name') # 对象.属性 = 属性值 时触发
def __setattr__(self, key, value):
# 给字典添加键值对的方式
self[key] = value # User 用户名 密码
class User(Models):
# 用户自定义,表名为 user_info
# table_name = 'user_info'
#
# obj = IntegerField(name='id', primary_key=True)
# print(obj.primary_key)
# print(obj.name)
# print(obj.default) # IntegerField字段类中的name属性 必须与User表中类属性同名
id = IntegerField(name='id', primary_key=True)
username = StringField(name='username')
password = StringField(name='password')
  • mysql_cntrol
import pymysql

# MySQL连接类

class MySQL:

    __instance = None

    # 单例模式
@classmethod
def singleton(cls):
if not cls.__instance:
cls.__instance = cls() return cls.__instance # 实例化MySQL类时,获取数据库连接对象,获取游标对象
def __init__(self):
self.mysql_client = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '123456',
charset = 'utf8',
database = 'orm_demo',
autocommit = True
) self.cursor = self.mysql_client.cursor(pymysql.cursors.DictCursor) # 自定义查询方法
def select(self, sql, args= None):
# 1、先提交查询sql语句
# select * from tabele;
# select * from table where id=%s;
self.cursor.execute(sql, args) # 2、获取返回的查询结果
# res ---> [{}, {}]
res = self.cursor.fetchall()
return res # 自定义提交sql语句方法, 比如inset ,update
def execute(self, sql, args): # 1、提交sql语句
# insert into table(字段) values(%s);
try:
self.cursor.execute(sql, args) except Exception as e:
print(e) def close(self): # 先关闭游标
self.cursor.close()
# 再关闭数据库连接
self.mysql_client.close() if __name__ == '__main__': mysal_obj1 = MySQL.singleton()
mysal_obj2 = MySQL.singleton()
print(id(mysal_obj1))
print(id(mysal_obj2))

初识orm的更多相关文章

  1. Hibernate框架 初识 ORM概念 搭建Hibernate环境 Hibernate Api

    ORM概念 在学习 Hibernate 之前,我们先来了解ORM   对象关系映射 O, Object  对象 R,Realtion 关系  (关系型数据库: MySQL, Oracle…) M,Ma ...

  2. Hibernate框架 初识 ORM概念

    Hibernate概述 Hibernate是一个ORM(对象关系映射)映射框架,它的核心思想就是在底层对JDBC进行了一次封装. 什么是框架 IT语境中的框架,特指为解决一个开放性问题而设计的具有一定 ...

  3. Django进阶Model篇—数据库操作(ORM)

    一.数据库配置 django 默认支持sqlite.mysql.oracle.postgresql数据库,像db2和sqlserver之类的数据库需要第三方的支持,具体详见https://docs.d ...

  4. Django(四) ORM 外键操作及初识Ajax

    一.内容回顾 1.Django请求的生命周期: ​ 路由系统 -> 视图函数(获取模板+数据 -> 渲染) -> 字符串返回给用户 2.路由系统: /index/ #-> 函数 ...

  5. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  6. day 67 orm初识 {code_first/db_first}

    1,我们是先创建一个django项目,要同时把app带上, 然后再django项目里面把settings部分设置好,按照我们一开始创建django项目的时候设置的那些,csrf以及templates还 ...

  7. ORM初识和数据库操作

    ORM简介 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使用描述对象和数据库之 ...

  8. 初识kbmmw 中的ORM

    在kbmmw 5.02.1 中,加入了ORM 的功能(这里可能和其他语言的定义不完全一样),我们就简单的认为 它就是一个类与数据库的转换吧.今天就先介绍一下如何通过kbmmw 的ORM 功能,实现类与 ...

  9. Android ORM——初识greenDAO 3及使用greenDAO 3前应该掌握的一些知识点(一)

    引言 总所周知,SQLite--内嵌于Android中一个占用内存极小的关系型,作为我们Android存储领域中重要的一员 ,或多或少都曾接触到数据库.即使Android系统中提供了很多操作SQLit ...

随机推荐

  1. iOS-使用Xcode自带单元测试UnitTest

    ![Uploading QQ20160129-3_262826.png . . .]####什么是单元测试?一听到单元测试这个词感觉很高端,其实单元测试就是为你的方法多专门写一个测试函数.以保证你的方 ...

  2. HDU1561 The more ,The better (树形背包Dp)

    ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先 ...

  3. centos7下ldap+kerberos实现单点登陆

    一. LDAP概念 http://wiki.jabbercn.org/index.php/OpenLDAP2.4%E7%AE%A1%E7%90%86%E5%91%98%E6%8C%87%E5%8D%9 ...

  4. Obeject.hasOwnProperty

    对象{ }要用for-in遍历对象内的属性,通过hasOwnProperty判断属性是否是对象本身的,而不是原型上的 数组[ ]可以通过forEach来遍历

  5. 【Eureka】服务发现调用

    [Eureka]服务发现调用 转载:https://www.cnblogs.com/yangchongxing/p/10779832.html 1.使用 Netfix Feign 客户端调用服务 首先 ...

  6. 2019百度阿里Java面试题(基础+框架+数据库+分布式+JVM+多线程)

    前言 很多朋友对面试不够了解,不知道如何准备,对面试环节的设置以及目的不够了解,因此成功率不高.通常情况下校招生面试的成功率低于1%,而社招的面试成功率也低于5%,所以对于候选人一定要知道设立面试的初 ...

  7. 12个超好用的IntelliJ IDEA 插件!你用过几个?

    一.前言 IntelliJ IDEA 如果说IntelliJ IDEA是一款现代化智能开发工具的话,Eclipse则称得上是石器时代的东西了. 其实笔者也是一枚从Eclipse转IDEA的探索者,随着 ...

  8. Android Studio 中java 文件报错红色J

    用常用的方法清除Android Studio的缓存然后重启,"File" -> "Invalidate Cashes / Restart" -> & ...

  9. 后缀数组SA入门(史上最晦涩难懂的讲解)

    参考资料:victorique的博客(有一点锅无伤大雅,记得看评论区),$wzz$ 课件(快去$ftp$%%%),$oi-wiki$以及某个人的帮助(万分感谢!) 首先还是要说一句:我不知道为什么我这 ...

  10. Asp.Net MVC中记录错误日志保存到本地txt文件

    为了方便查询系统出错弄个错误日志出来对于维护运维来说是很有必要的. 1.在Asp.Net MVC项目中的App_Start添加一个用于处理异常类的文件ErrorLog让他继承HandleErrorAt ...