python oracle orm_Python ORM

本章内容

ORM介绍

如果写程序用pymysql和程序交互,那是不是要写原生sql语句。如果进行复杂的查询,那sql语句就要进行一点一点拼接,而且不太有重用性,扩展不方便。而且写的sql语句可能不高效,导致程序运行也变慢。

为了避免把sql语句写死在代码里,有没有一种方法直接把原生sql封装好了并且以你熟悉的方式操作,像面向对象那样?

ORM(object relational mapping),就是对象映射关系程序,简单来说我们类似Python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言。

ORM 相当于把数据库也给你实例化了,在代码操作MySQL中级又加了orm这一层。

ORM的优点:

隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。

ORM使我们构造固化数据结构变得简单易行。

缺点:

无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。

sqlalchemy安装

安装sqlalchemy

1 pip install SQLAlchemy2 pip install pymysql3 #由于mysqldb依然不支持py3,所以这里我们用pymysql与sqlalchemy交互

4 #虽然大家可能在python2.x中用习惯了mysqldb,但是在python3.x中已经不支持那个组件了。取而代之的是:pymysql

sqlalchemy基本使用

Dialect(数据库方言)用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

1 MySQL-Python2 mysql+mysqldb://:@[:]/

3

4 pymysql5 mysql+pymysql://:@/[?]6

7 MySQL-Connector8 mysql+mysqlconnector://:@[:]/

9

10 cx_Oracle11 oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]

基本的增、删、改、查

importsqlalchemyfrom sqlalchemy importcreate_enginefrom sqlalchemy.ext.declarative importdeclarative_basefrom sqlalchemy importColumn, Integer, Stringfrom sqlalchemy.orm importsessionmaker

Base =declarative_base()

classUser(Base): __tablename__ = 'user' #表名

id = Column(Integer, primary_key=True) username = Column(String(100)) password = Column(String(100))

#定义函数的输出方式,不然会以对象的形式输出,<__main__.userobject>   def __repr__(self):

return 'name:%s,password:%s'%(self.username,self.password)

#创建实例并连接数据库

engine = create_engine("mysql+mysqldb://woniu:1234@59.110.12.72:3306/wangjin?charset=utf8",echo=True) #echo 输出日志的信息 #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例

db_session = sessionmaker(bind=engine) #实例和engine绑定

session = db_session() #生成session实例,相当于游标

#add user

user_obj = User(username='hello',password='python') #生成你要创建的数据对象

session.add(user_obj) #把要创建的数据对象添加到这个session里

session.commit() printuser_obj.username print user_obj.password #现此才统一提交,创建数据

#query

my_user = session.query(User).filter_by(username='hello').first() #根据条件去查询

printmy_user.username,my_user.password

#edit

edit_user = session.query(User).filter_by(username='hello').all() edit_user.username = 'woniu' #赋值

edit_user.password = 'hehe'

session.commit() printmy_user.username,my_user.password

#del

del_user = session.query(User).filter_by(username='hello').all() for i indel_user: session.delete(i) session.commit()

#rallback

my_user = Session.query(User).filter_by(id=1).first()

my_user.name = "Jack"

fake_user = User(name='Rain', password='12345')

Session.add(fake_user)

print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #这时看session里有你刚添加和修改的数据

Session.rollback() #此时你rollback一下

print(Session.query(User).filter(User.name.in_(['Jack','rain'])).all() ) #再查就发现刚才添加的数据没有了。

# Session

# Session.commit()

filter_by与filter的区别

my_user2 = Session.query(User).filter_by(id=27).all() #filter_by相等用‘=’

my_user3= Session.query(User).filter(User.id==27).all() #filter相等用‘==’

用法不同而已,filter 可以像写 sql 的 where 条件那样写 > < 等条件,但引用列名时,需要通过 类名.属性名 的方式。 filter_by 可以使用 python 的正常参数传递方法传递条件,指定列名时,不需要额外指定类名。,参数名对应名类中的属性名

多条件查询

objs = Session.query(User).filter(User.id>0).filter(User.id<7).all()

上面2个filter的关系相当于 user.id >1 AND user.id <7 的效果

from sqlalchemy import and_, or_ #且和or的关系

ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all() #条件以and方式排列

ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all() #条件以or方式排列

分组统计

from sqlalchemy importfuncprint(Session.query(func.count(User.name),User.name).group_by(User.name).all() )

Session.query(User).filter(User.name.like("Ra%")).count().all()

#输出结果

4

[(1, 'alex'), (1, 'chongyang'), (4, 'liming')

外键关联

importsqlalchemyfrom sqlalchemy importcreate_engine,func,ForeignKeyfrom sqlalchemy.ext.declarative importdeclarative_basefrom sqlalchemy importColumn,Integer,Stringfrom sqlalchemy.orm importsessionmaker,relationship

engine= create_engine("mysql+pymysql://woniu:123456@59.110.12.72/txadmin",encoding='utf-8')

Base=declarative_base()classStudent(Base):__tablename__ = 'student'id= Column(Integer,primary_key=True)

name= Column(String(32))

password= Column(String(64))def __repr__(self):return 'name:%s,password:%s'%(self.name,self.password)classAddress(Base):__tablename__ = 'addresses'id= Column(Integer,primary_key=True)

email_address= Column(String(32),nullable=False)

user_id= Column(Integer,ForeignKey('student.id'))

#允许你在student表里通过backref字段反向查出所有它在addresses表里的关联项

student= relationship('Student',backref='addresses')def __repr__(self):return 'Address(email_address="%s")'%self.email_address

Base.metadata.create_all(engine)

db_session= sessionmaker(bind=engine)

session=db_session()#add user#user_obj = Student(name = 'alex',password='1234')#session.add(user_obj)#session.commit()#print(user_obj.name)#print(user_obj.password)

# 如果有多个对象需要添加,可以如下使用

session.add_all([obj1,obj2,obj3])

#add_address#add_obj = Address(email_address = 'hebeisheng',user_id = '2')#session.add(add_obj)#session.commit()##query## my_user = session.query(Student).filter_by(name='liming').all()#res = session.query(func.count(Student.name),Student.name).group_by(Student.name).all()#

#res1 = session.query(Student).filter(Student.name.like('li%')).count()#print(res1)#print(res)

#obj = session.query(Student).all()#

#

#for i in obj:#print(i.addresses)

#在addr_obj里直接插关联的student表

#addr_obj = session.query(Address).all()#for i in addr_obj:#print(i.student.name)

#通过student对象方差关联的address的记录obj= session.query(Student).filter_by(name='liming').all()[2]print(obj.addresses)

#添加关联对象

obj.addresses= [Address(email_address="r1@126.com"),Address(email_address="8888888.com")]

session.commit()print(obj.addresses)

#运行结果

[]

[Address(email_address="r1@126.com"), Address(email_address="8888888.com")]

#首先 第三个李明是没有设置对应的地址的,所以为空,设置完毕后就可以看到对应的值了

多外键关联

customer 表中的 billing_address_id 关联 address表的ID

customer 表中的 shipping_address_id 关联 address表的ID

importsqlalchemyfrom sqlalchemy importInteger,Column,String,ForeignKey,create_enginefrom sqlalchemy.ext.declarative importdeclarative_basefrom sqlalchemy.orm importrelationship,sessionmaker

engine= create_engine("mysql+pymysql://woniu:123456@59.110.12.72/txadmin",encoding='utf-8')

Base=declarative_base()classCustomer(Base):__tablename__ = 'customer'id= Column(Integer,primary_key=True)

name= Column(String(32))

billing_address_id= Column(Integer,ForeignKey('address.id')) #建立外键

shipping_address_id = Column(Integer,ForeignKey('address.id')) #建立外键

billing_address= relationship('Address',foreign_keys=[billing_address_id]) #注意这两行

shipping_address = relationship('Address',foreign_keys=[shipping_address_id])#def __repr__(self):

#return '{name:%s,billing_addres:%s,shipping_address:%s}'%(self.name,self.billing_address,self.shipping_address)

classAddress(Base):__tablename__ = 'address'id= Column(Integer,primary_key=True)

street= Column(String(32))

city= Column(String(32))

state= Column(String(32))def __repr__(self):returnself.city

Base.metadata.create_all(engine)

db_session= sessionmaker(bind=engine)

session=db_session()#obj2 = Address(street = 'shipping_address',city='test',state='eee')#obj3 = Address(street = 'billing_address',city='test',state='eee')#session.add(obj2)#session.add(obj3)#

#session.commit()#

#

#obj = Customer(name = 'nima',billing_address = obj2,shipping_address = obj3)#session.add(obj)#session.commit()

res= session.query(Customer).filter(Customer.name == 'nima').first()print(res.name,dir(res))print(res.billing_address,res.shipping_address) #可以关联得到外键,通过customer表,查看address表

多外键

mysql> descaddress;+--------+-------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+--------+-------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| street | varchar(32) | YES | | NULL | |

| city | varchar(32) | YES | | NULL | |

| state | varchar(32) | YES | | NULL | |

+--------+-------------+------+-----+---------+----------------+

4 rows in set (0.00sec)

mysql> desccustomer;+---------------------+-------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+---------------------+-------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| name | varchar(32) | YES | | NULL | |

| billing_address_id | int(11) | YES | MUL | NULL | |

| shipping_address_id | int(11) | YES | MUL | NULL | |

+---------------------+-------------+------+-----+---------+----------------+

4 rows in set (0.00sec)

mysql> select * fromcustomer;+----+---------+--------------------+---------------------+

| id | name | billing_address_id | shipping_address_id |

+----+---------+--------------------+---------------------+

| 6 | liming | 6 | 7 |

| 7 | xiaohua | 4 | 5 |

| 8 | xiaohua | 4 | 5 |

| 9 | xiaohua | 14 | 15 |

| 10 | nima | 16 | 17 |

+----+---------+--------------------+---------------------+

5 rows in set (0.01sec)

mysql> select * fromaddress;+----+------------------+------+-------+

| id | street | city | state |

+----+------------------+------+-------+

| 3 | uuu | rrr | eee |

| 4 | shipping_address | rrr | eee |

| 5 | shipping_address | rrr | eee |

| 6 | shipping_address | rrr | eee |

| 7 | billing_address | rrr | eee |

| 8 | shipping_address | qqq | eee |

| 9 | billing_address | www | eee |

| 10 | shipping_address | qqq | eee |

| 11 | billing_address | www | eee |

| 12 | shipping_address | qqq | eee |

| 13 | billing_address | www | eee |

| 14 | shipping_address | test | eee |

| 15 | billing_address | test | eee |

| 16 | shipping_address | test | eee |

| 17 | billing_address | test | eee |

+----+------------------+------+-------+

15 rows in set (0.00sec)

mysql>

mysql 表信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端校验和后端校验区别

前台验证数据格式 后台验证的是数据的正确性 当下流行的系统架构方案中&#xff0c;前端和后端都是分离开的。 目的&#xff1a;① 为了方便前端开发人员和后端开发人员可以同时开发&#xff1b;② 前后端分离也使得前后端的代码可以分开进行管理&#xff0c;方便了各自的版…

unittest-ddt报错AttributeError: type object ‘forTestDDT‘ has no attribute ‘test_2‘

unittest 添加多个ddt数据驱动后&#xff0c;报错&#xff1a; FAILED (errors1)Error Traceback (most recent call last):File "D:\Anaconda3\lib\unittest\case.py", line 60, in testPartExecutoryieldFile "D:\Anaconda3\lib\unittest\case.py", lin…

socket timeout是什么引起的_MySQL C API 参数 MYSQL_OPT_READ_TIMEOUT 的一些行为分析

作者&#xff1a;戴岳兵MYSQL_OPT_READ_TIMEOUT 是 MySQL c api 客户端中用来设置读取超时时间的参数。在 MySQL 的官方文档中&#xff0c;该参数的描述是这样的&#xff1a;MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *)The timeout in seconds for each attempt t…

python动态爬取知乎_python爬虫从小白到高手 Day2 动态页面的爬取

今天我们说说动态页面的抓取&#xff0c;动态页面的概念不是说网页上的内容是活动的&#xff0c;而是刷新的内容由Ajax加载&#xff0c;页面的URL没有变化&#xff0c;具体概念问度娘。就以男人都喜欢的美女街拍为例&#xff0c;对象为今日头条。chrome打开今日头条 ->搜索开…

Python操作文件,报FileNotFoundError: [Error 2] No such file or directory错误

python操作文件时&#xff0c;报No such file or directory错误。 多次检查目录、文件名、语法都是对的。 折腾一番后&#xff0c;打开文件所在文件夹&#xff0c;并显示所有文件后缀名&#xff0c;才发现此文件并没有txt后缀名 解决方法&#xff1a; 添加文件的.txt后缀名&a…

python多标签分类_如何通过sklearn实现多标签分类?

sklearn支持多类别(Multiclass)分类和多标签(Multilabel)分类&#xff1a;多类别分类&#xff1a;超过两个类别的分类任务。多类别分类假设每个样本属于且仅属于一个标签&#xff0c;类如一个水果可以是苹果或者是桔子但是不能同时属于两者。多标签分类&#xff1a;给每个样本分…

练习ddt-file_data时,报错UnboundLocalError local variable ‘value‘ referenced before assignment

错误原因就是&#xff0c;在xx.yml中的内容无效 更改之前&#xff1a; 更改之后&#xff1a; 注意冒号后面要有空格 改完之后运行就能正确读取到了

python筛选数据求均值_Python Pandas实现数据分组求平均值并填充nan的示例

Python实现按某一列关键字分组&#xff0c;并计算各列的平均值&#xff0c;并用该值填充该分类该列的nan值。DataFrame数据格式fillna方式实现groupby方式实现DataFrame数据格式以下是数据存储形式&#xff1a;fillna方式实现1、按照industryName1列&#xff0c;筛选出业绩2、筛…

HTMLTestRunner.py内容

HTMLTesstRunner.py 修改后内容如下&#xff1a; """ A TestRunner for use with the Python unit testing framework. It generates a HTML report to show the result at a glance.The simplest way to use this is to invoke its main method. E.g.import u…

卷积神经网络原理_人脸识别背后,卷积神经网络的数学原理原来是这样的

在自动驾驶、医疗以及零售这些领域&#xff0c;计算机视觉让我们完成了一些直到最近都被认为是不可能的事情。卷积神经网络可能是这一巨大成功背后的关键组成模块。这次&#xff0c;我们将要使用卷积神经网络的思想来拓宽我们对神经网络工作原理的理解。简介过去我们接触到了密…

unittest读取ddt之-元组,嵌套元组,字典

注&#xff1a; &#xff08;1&#xff09;ddt数据驱动中&#xff0c;测试用例的执行次数是由data&#xff08;&#xff09;传参的个数决定。传几个参数&#xff0c;就是执行几次测试用例。 &#xff08;2&#xff09;如果传的是多个元组&#xff08;列表&#xff09;,那么可…

负载均衡策略_常见的负载均衡策略

轮询(Round Robin)&#xff1a; 这种方法就会将收到的请求循环分配到服务器集群中的每台机器&#xff0c;即有效服务器。如果使用这种方式&#xff0c;所有的标记进入虚拟服务的服务器应该有相近的资源容量以及敷在相同的应用程序。如果所有的服务有相同或者相近的性能那么选择…

unittest-读取yaml文件

注&#xff1a; &#xff08;1&#xff09;yaml文件详解 yaml是一种数据格式&#xff0c;类似txt,excel,json 它只有两种数据类型&#xff1a; map对象&#xff08;键值对&#xff0c;冒号后需要有空格&#xff09; list列表对象&#xff0c;以-开头 读取之后是一个不定长…

白盒测试-修正条件判定覆盖

当程序中的判定语句包含多个条件时&#xff0c;运用多条件覆盖方法进行测试&#xff0c;其条件取值组合数目是非常大的。 修正条件判定覆盖要求在一个程序中每一种输入输出至少得出现一次&#xff0c;在程序中的每一个条件必须产生所有可能的输出结果至少一次&#xff0c;并且…

springboot整合shiro_Springboot整合Shiro:简洁的身份认证

简单的web应用进行身份认证的流程&#xff1a;1.对未认证的用户请求进行拦截&#xff0c;跳转到认证页面。2.用户通过用户名密码及其他凭证进行身份认证&#xff0c;认证成功跳转成功页面&#xff0c;认证失败提示相关失败信息。根据流程&#xff0c;采用shiro进行快速开发。1.…

python回车键绑定按钮_python tkinter 绑定回车键

# _*_ coding:utf-8_*_from Tkinter import *def submit(ev None):p.set(u.get())root Tk()root.title("测试")frame Frame(root)frame.pack(padx8, pady8, ipadx4)lab1 Label(frame, text"获取:")lab1.grid(row0, column0, padx5, pady5, stickyW)#绑…

2024年【安全生产监管人员】考试及安全生产监管人员模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【安全生产监管人员】考试及安全生产监管人员模拟考试题库&#xff0c;包含安全生产监管人员考试答案和解析及安全生产监管人员模拟考试题库练习。安全生产模拟考试一点通结合国家安全生产监管人员考试最新大纲…

PICT工具安装使用

1、安装PICT 通过下载安装包pict33.msi&#xff0c; 链接&#xff1a;https://pan.baidu.com/s/1YWIA5XLNI0MMFkiQ-EqZ9w 提取码&#xff1a;ho7g 解压安装&#xff0c;安装成功后验证&#xff1a;打开cmd命令终端&#xff0c;输入pict显示如下即证明安装成功。 2、新建Mod…

茜在人名可以读xi吗_甘肃中专学校:初中毕业可以读大专吗?

初中毕业到兰州中专学校可以读大专吗?许多学生因为成绩的关系可能没能上普通高中&#xff0c;但是他们现在还不具备任何的专业知识和能力进入社会。很多孩子都想通过读大专具备进入社会的能力&#xff0c;那么初中毕业的学生是否能够读大专呢?成人高考初中毕业之后是可以读大…

测试用例设计思路

测试用例编写思路&#xff1a; 首先是明确测试范围&#xff1a; 接口测试 功能测试 界面测试&#xff08;界面友好性、易用性、一致性&#xff09; 兼容性测试&#xff08;不同类型、型号手机、系统&#xff08;手机系统、桌面系统&#xff09;、分辨率、浏览器及其版本&a…