Python库之SQLAlchemy
一、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.3、更新数据
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.4、删除数据
创建删除语句时,既可以使用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.2、插入
user = User(1, '小明')
session.add(user)
session.commit()
3.3、查询
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.3.1、控制查询中的列数
print(session.query(user.name).first())
3.3.2、排序
for record in sesssion.query(user).order_by(user.name):
print(user.name)
3.3.3、限制返回结果集的条数
query = session.query(user).order_by(user.name).[:2]
print([result.user_name for result in query])
3.3.4、内置SQL函数和标签
from sqlalchemy import func
inv_count = session.query(func.sum(user.name)).scalar()
print(inv_count)
3.3.5、过滤
record = session.query(user).filter(user.name == '小华')
print(record)
3.4、更新数据
query = session.query(user)
xm_user = query.filter(user.user_name == '小华').first()
xm_user.name = 'robin'
session.commit()
print(xm_user.quantity)
3.5、删除数据
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)
参考资料
Python库之SQLAlchemy的更多相关文章
- 顶级Python库
绝不能错过的24个顶级Python库 Python有以下三个特点: · 易用性和灵活性 · 全行业高接受度:Python无疑是业界最流行的数据科学语言 · 用于数据科学的Python库的数量优势 事实 ...
- 20.Python笔记之SqlAlchemy使用
Date:2016-03-27 Title:20.Python笔记之SqlAlchemy使用 Tags:python Category:Python 作者:刘耀 博客:www.liuyao.me 一. ...
- Python 库大全
作者:Lingfeng Ai链接:http://www.zhihu.com/question/24590883/answer/92420471来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非 ...
- 20个必不可少的Python库
转载:http://www.python123.org/tutorials/58b41f2a28c8f30100bd41dc 读者们好.今天我将介绍20个属于我常用工具的Python库,我相信你看完之 ...
- 哪些 Python 库让你相见恨晚?【转】
原文链接:https://www.zhihu.com/question/24590883/answer/92420471 原文链接:Python 资源大全 ---------------- 这又是一个 ...
- Python 库/模块/工具收集
1 算法 1.1 字符串处理 re 正则表达式的标准库. StringIO / cStringIO 以读写文件的方式来操作字符串(有点类似于内存文件). cStringIO 是 C 语言实现的,提供高 ...
- Python库,让你相见恨晚的第三方库
环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具.pyenv – 简单的 Python 版本管理工具.Vex – 可以在虚拟环境中执行命令.virt ...
- Python 库,资源
库名称简介 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式 ...
- Python资源 --Python库
环境管理 管理 Python 版本和环境的工具 pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. virtualenv – 创建独立 Python 环境的工 ...
随机推荐
- .net core3.1中实现简单的jwt认证
1.创建项目 使用visual studio创建一个名为JwtDemo的空项目,创建后如图 2.添加依赖项 在nuget包管理器中搜索 Microsoft.AspNetCore.Authenticat ...
- Docker Compose 搭建 Redis Cluster 集群环境
在前文<Docker 搭建 Redis Cluster 集群环境>中我已经教过大家如何搭建了,本文使用 Docker Compose 再带大家搭建一遍,其目的主要是为了让大家感受 Dock ...
- leetcode刷题-78子集
题目 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3]输出:[ [3], [1], [2] ...
- 一个SQL查询连续三天的流量100以上的数据值【SQql Server】
题目 有一个商场,每日人流量信息被记录在这三列信息中:序号 (id).日期 (date). 人流量 (people).请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于10 ...
- Java并发编程之闭锁与栅栏
一.前言 闭锁与栅栏是在多线程编程中的概念,因为在多线程中,我们不能控制线程的执行状态,所以给线程加锁,让其按照我们的想法有秩序的执行. 闭锁 CountDownLatch,实例化时需要传入一个int ...
- robotframework安装与运行(ride.py1.7.4.2命令报错)(win10+python3.8.1)
首先,robotframework必须在python的环境下运行 所以你的电脑里必须有python3.x的环境先. 上古时期的robotframework只支持python2,不过python2都已经 ...
- linux 信号机制
文章目录 1. 实时信号非实时信号 2. 信号状态: 3. 信号生命周期: 4. 信号的执行和注销 信号掩码和信号处理函数的继承 信号处理函数的继承 信号掩码的继承 sigwait 与多线程 sigw ...
- [LeetCode]26. 删除排序数组中的重复项(数组,双指针)
题目 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下 ...
- [Leetcode]585. 2016年的投资(MySQL)
题目 写一个查询语句,将 2016 年 (TIV_2016) 所有成功投资的金额加起来,保留 2 位小数. 对于一个投保人,他在 2016 年成功投资的条件是: 他在 2015 年的投保额 (TIV_ ...
- JDK15正式发布,划时代的ZGC同时宣布转正
你发任你发,我用Java8.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BA ...