热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PythonSQLAlchemy库的使用方法详解

本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。

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.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库的资料请关注编程笔记其它相关文章!

原文链接:https://www.cnblogs.com/lit10050528/p/13806516.html


推荐阅读
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • Java 中的 BigDecimal pow()方法,示例 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 探讨如何从数据库中按分组获取最大N条记录的方法,并分享新年祝福。本文提供多种解决方案,适用于不同数据库系统,如MySQL、Oracle等。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • Java 中 Writer flush()方法,示例 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • Java 类成员初始化顺序与数组创建
    本文探讨了Java中类成员的初始化顺序、静态引入、可变参数以及finalize方法的应用。通过具体的代码示例,详细解释了这些概念及其在实际编程中的使用。 ... [详细]
  • 本文探讨了在Oracle数据库中,动态SQL语句的执行及其对事务管理的影响,特别是关于回滚操作的有效性。重点讨论了一个具体场景:将预警短信从当前表迁移到历史表时遇到的字段长度不匹配问题及相应的异常处理。 ... [详细]
  • Java 中的月减()方法 ... [详细]
  • 本文探讨了2012年4月期间,淘宝在技术架构上的关键数据和发展历程。涵盖了从早期PHP到Java的转型,以及在分布式计算、存储和网络流量管理方面的创新。 ... [详细]
  • 本文详细介绍了在 MySQL、SQL Server 和 Oracle 数据库中如何使用分组和排序功能。涵盖了聚集函数的应用、HAVING 子句的作用以及特定数据库中的独特方法,如 SQL Server 的 ROW_NUMBER() 函数和 Oracle 的相关特性。 ... [详细]
author-avatar
安安ahui
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有