Python SQLAlchemy库的使用方法


Posted in Python onOctober 13, 2020

一、SQLAlchemy简介

1.1、SQLAlchemy是什么?

sqlalchemy是一个python语言实现的的针对关系型数据库的orm库。可用于连接大多数常见的数据库,比如Postges、MySQL、SQLite、Oracle等。

1.2、为什么要使用SQLAlchemy?

它将你的代码从底层数据库及其相关的SQL特性中抽象出来。

1.3、SQLAlchemy提供了两种主要的使用模式

  • SQL表达式语言(SQLAlchemy Core)
  • ORM

1.4、应该选择哪种模式?

虽然你使用的框架中已经内置了ORM,但是希望添加更强大的报表功能,请选用Core。
如果你想在一个一模式为中心的视图中查看数据(用户类似于SQL),请使用Core。
如果你的数据不需要业务对象,请使用Core。
如果你要把数据看作业务对象,请使用ORM。
如果你想快速创建原型,请使用ORM。
如果你需要同事使用业务对象和其他与问题域无关的数据,请组合使用Core和ORM。

1.5、连接数据库

要连接到数据库,需要先创建一个SQLAlchemy引擎。SQLAlchemy引擎为数据库创建一个公共接口来执行SQL语句。这是通过包装数据库连接池和方言(不同数据库客户端)来实现的。

SQLAlchemy提供了一个函数来创建引擎。在这个函数中,你可以指定连接字符串,以及其他一些可选的关键字参数。

from sqlalchemy import create_engine
engine = create_engine('sqlite:///cookies.db')
engine1 = create_engine('sqlite:///:memory:')
engine2 = create_engine('sqlite://///home/cookiemonster/cookies.db')
engine3 = create_engine('sqlite:///c:\\Users\\cookiemonster\\cookies.db')

engine_mysql = create_engine('mysql+pymysql://cookiemonster:chocolatechip', '@mysql01.monster.internal/cookies', pool_recycle=3600)

1.6、模式和类型

为了访问底层数据库,SQLAlchemy需要用某种东西来代表数据库中的表。为此,可以使用下面三种方法总的一种:

使用用户定义的Table对象
使用代表数据表的声明式类
从数据库中推断

二、SQLAlchemy core

SQLAlchemy core定义表结构使用的是1.5中说的第1种方式。table对象包含一系列带有类型的列和属性,它们与一个常见的元数据容器相关联。

元数据可以看作是一种Table对象目录。这些表可以通过MetaData.tables来访问。

2.1、定义表结构

在SQLAlchemy Core中,我们通过Table构造函数来初始化Table对象。我们要在构造函数中提供MetaData对象(元数据)和表名,任何其他参数都被认为是列对象。列是通过Column()函数创建的。

from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import MedaData

metadata = MetaData()
user = table('user', metadata, 
			 Column(id, Integer(), primary_key=True), 
			 Column(name, String(255)), 
)

engine = create_engine('sqlite:///:memory:')
metadata.create_all(engine) # 表的持久化

2.2、插入数据

首先创造一条insert语句,用来把小明放入user表中。为此,先调用user表的insert()方法,然后再使用values()语句,关键字参数为各个列及相应值:

ins = user.insert().values(
	id=1, 
 name='小明'
)
print(str(ins))

到此仅仅只是创建了一个inset语句,还没有真正执行呢,接下来执行插入操作:

connection = engine.connect()
result = connection.execute(ins)
print(result.inserted_primary_key)

2.3、查询数据

构建查询时,要用到select函数,它类似于标准SQL SELECT语句。

from sqlalchemy.sql import select
s = select([user])
# 可以使用str(s)查看数据库看到的语句
print(str(s))
rp = connection.execute(s)
results = rp.fetchall()

2.3.1、ResultProxy

execute()函数的返回值是一热ResultProxy对象,它允许使用索引、名称或Column对象进行访问。

使用ResultProxy处理行

first_row = results[0]
first_row[1]
first_row.name
first_row[user.c.name]

迭代ResultProxy

rp = connection.execute(s)
for record in rp:
	print(record.user_name)

使用方法访问结果

rp.first() # 若有记录,则返回第一个记录并关闭连接
rp.fetchone() # 返回一行,并保持光标为打开状态,以便你做更多获取调用
rp.scalar() # 入股查询结果是包含一个列的单条记录,则返回单个值

2.3.2、控制查询中的列数

s = select([user.c.name])
rp = connection.execute(s)
print(rp.keys())
result = rp.first()

2.3.3、排序

s = select([user.c.name])
s = s.order_by(user.c.name)
rp = connection.execute(s)
for user in rp:
	print(user.name)

2.3.4、限制返回结果集的条数

s = select([user.c.name])
s = s.order_by(user.c.name)
s = s.limit(2)
rp = connection.execute(s)
for user in rp:
	print(user.name)

2.3.5、内置SQL函数和标签

from sqlalchemy.sql import func
s = select([func.sum(user.c.score)])
rp = connection.execute(s)
print(rp.scalar())

2.3.6、过滤

对查询过滤是通过添加where()语句来完成的。

s = select([user]).where(user.c.name == '小明')
rp = connection.execute(s)
record = rp.first()
print(record.items())

这里只是介绍了常用的查询方法,更多复杂的查询请查阅官方文档。

2.4、更新数据

update()方法和前面的insert()方法很相似,它们的语法几乎完全一样,但是update()可以指定一个where()子句,用来指出要更新哪些行。

from sqlalchemy import update
u = update(user).where(user.c.name == '小明')
u = u.values(name='小华')
result = connection.execute(u)
print(result.rowcount)

2.5、删除数据

创建删除语句时,既可以使用delete()函数,也可以使用表的delete()方法。与insert()和update()不同,delete()不接收值参数,只接收一个可选where子句,用来指定删除范文。

from sqlalchemy import delete
u = delete(user).where(user.c.name == '小华')
result = connection.execute(u)
print(result.rowcount)

注意:

更多的高级操作:连接、别名、分组、链式调用、原始查询等,请查阅官方文档。

2.5、事务

通过connection.begin()开启一个事务,返回一个transaction对象,接下来根据执行的情况调用transaction.commit()提交修改或者调用transaction.rollback()回滚操作。

三、SQLAlchemy orm

SQLAlchemy orm定义表结构使用的是1.5中说的第2种方式。通过定义一个类,它继承自一个名为declarative_base的特殊基类。declarative_base把元数据容器和映射器(用来把类映射到数据表)结合在一起。

orm使用的类应该满足如下四个要求:

  • 继承自declarative_base对象。
  • 包含__tablename__,这是数据库中使用的表名。
  • 包含一个或多个属性,它们都是column对象。
  • 确保一个或多个属性组成主键。

3.1、定义表结构:

from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
class User(Base):
 __tablename__ = 'user'
 
	id = Column(Integer, primary_key=True)
	name = Column(String(255))
	
engine = create_engine('sqlite:///')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

3.2、会话(session)

会话是SQLAlchemy ORM和数据库交互的方式。它通过引擎包装数据库连接,并为通过会话加载或与会话关联的对象提供标识映射(identity map)。标识映射是一种类似于缓存的数据结构,它包含由对象表和主键确定的一个唯一的对象列表。会话还包装了一个事务,这个事务将一直保持打开状态,直到会话提交或回滚。

为创建会话,SQLAlchemy提供了一个sessionmaker类,这个类可以确保在整个应用程序中能够使用相同的参数创建会话。sessionmaker类通过创建一个Session类来实现这一点,Session类是根据传递给sessionmaker工厂的参数配置的。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=engine)
session = Session()

3.3、插入

user = User(1, '小明')
session.add(user)
session.commit()

3.4、查询

for row in session.query(User):
	print(row.id, row.name)

注意:session.query()的返回值是Query对象,不能使用它的返回值作为查询结果。关于Query对象的用法,请参阅:https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query

常用Query对象的方法:

q = session.query(User)
q.count() # 获取查询结果的数量
q.all() # 返回查询结果的list,会触发执行SQL查询
q.get(id) # 根据primary_key查询单个对象
q.as_scalar() # 返回此次查询的SQL语句

3.4.1、控制查询中的列数

print(session.query(user.name).first())

3.4.2、排序

for record in sesssion.query(user).order_by(user.name):
	print(user.name)

3.4.3、限制返回结果集的条数

query = session.query(user).order_by(user.name).[:2]
print([result.user_name for result in query])

3.4.4、内置SQL函数和标签

from sqlalchemy import func
inv_count = session.query(func.sum(user.name)).scalar()
print(inv_count)

3.4.5、过滤

record = session.query(user).filter(user.name == '小华')
print(record)

3.5、更新数据

query = session.query(user)
xm_user = query.filter(user.user_name == '小华').first()
xm_user.name = 'robin'
session.commit()
print(xm_user.quantity)

3.6、删除数据

query = session.query(user)
xm_user = query.filter(user.user_name == '小华').first()
session.delete(xm_user)
session.commit()
print(xm_user)

注意:

这里简单介绍了SQLAlchemy orm的常见用法,更高级的用法请查阅官方文档。

四、反射

使用反射技术可以利用先用数据库填充SQLAlchemy对象。

4.1、反射单个表

创建初始对象:

from sqlalchemy import Metadata, create_engines
metadata = MetaData()
engine = reate_engine('sqlite:///')

反射Artist表

from sqlalchmy impport Table
artist = Table('Artist', metadata, autoload=True, autoload_with=engine)

4.2、反射整个数据库

metadata.reflect(bind=engine)

参考资料

https://docs.sqlalchemy.org/en/13/core/type_basics.html#generic-types

以上就是Python SQLAlchemy库的使用方法的详细内容,更多关于Python SQLAlchemy库的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
用Python创建声明性迷你语言的教程
Apr 13 Python
pygame学习笔记(1):矩形、圆型画图实例
Apr 15 Python
python实现class对象转换成json/字典的方法
Mar 11 Python
使用Python写CUDA程序的方法
Mar 27 Python
Python selenium抓取微博内容的示例代码
May 17 Python
django manage.py扩展自定义命令方法
May 27 Python
对pandas中Series的map函数详解
Jul 25 Python
Python设计模式之模板方法模式实例详解
Jan 17 Python
python命名空间(namespace)简单介绍
Aug 10 Python
解决python gdal投影坐标系转换的问题
Jan 17 Python
Python修改列表值问题解决方案
Mar 06 Python
python中对二维列表中一维列表的调用方法
Jun 07 Python
Pycharm github配置实现过程图解
Oct 13 #Python
详解numpy.ndarray.reshape()函数的参数问题
Oct 13 #Python
Python求区间正整数内所有素数之和的方法实例
Oct 13 #Python
python关于倒排列的知识点总结
Oct 13 #Python
Python如何使用ElementTree解析xml
Oct 12 #Python
Django ModelForm组件原理及用法详解
Oct 12 #Python
Python ConfigParser模块的使用示例
Oct 12 #Python
You might like
用PHP实现浏览器点击下载TXT文档的方法详解
2013/06/02 PHP
JavaScript 学习笔记(十三)Dom创建表格
2010/01/21 Javascript
改善用户体验的五款jQuery插件分享
2011/05/22 Javascript
jquery的ajax()函数传值中文乱码解决方法介绍
2012/11/08 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
2013/07/05 Javascript
IE浏览器中图片onload事件无效的解决方法
2014/04/29 Javascript
javascript父子页面通讯实例详解
2015/07/17 Javascript
javascript每日必学之条件分支
2016/02/17 Javascript
javascript实现标签切换代码示例
2016/05/22 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
详解js的延迟对象、跨域、模板引擎、弹出层、AJAX【附实例下载】
2016/12/19 Javascript
基于HTML5+JS实现本地图片裁剪并上传功能
2017/03/24 Javascript
JavaScript的词法结构精华篇
2018/10/17 Javascript
vue+eslint+vscode配置教程
2019/08/09 Javascript
微信小程序实现购物车代码实例详解
2019/08/29 Javascript
js实现删除json中指定的元素
2020/09/22 Javascript
实现vuex原理的示例
2020/10/21 Javascript
原生js实现自定义难度的扫雷游戏
2021/01/22 Javascript
python实现的文件同步服务器实例
2015/06/02 Python
Django如何实现内容缓存示例详解
2017/09/24 Python
Python模块搜索路径代码详解
2018/01/29 Python
Django框架实现的简单分页功能示例
2018/12/04 Python
详解Python3 pickle模块用法
2019/09/16 Python
Python如何使用内置库matplotlib绘制折线图
2020/02/24 Python
Pandas DataFrame求差集的示例代码
2020/12/13 Python
IE浏览器单独写CSS样式的几种方法
2014/10/14 HTML / CSS
MCM英国官网:奢侈皮具制品
2017/04/18 全球购物
Omio俄罗斯:一次搜索公共汽车、火车和飞机的机票
2018/11/17 全球购物
Michael Kors香港官网:美国奢侈品品牌
2019/12/26 全球购物
大学军训感言1500字
2014/03/09 职场文书
大学生求职信
2014/06/17 职场文书
部队2014年终工作总结
2014/11/27 职场文书
八年级上册语文教学计划
2015/01/22 职场文书
新员工入职欢迎词
2015/01/23 职场文书
周一给客户的问候语
2015/11/10 职场文书
uniapp 微信小程序 自定义tabBar 导航
2022/04/22 Javascript