当前位置: 代码网 > it编程>前端脚本>Python > Python中SQLAlchemy库的使用方法分析

Python中SQLAlchemy库的使用方法分析

2024年08月13日 Python 我要评论
1. 基本知识一、orm (对象关系映射):sqlalchemy 是python sql工具包和对象关系映射器(orm),允许python开发者在应用程序中使用sql来交互,而无需处理数据库的具体细节

1. 基本知识

一、orm (对象关系映射)

  • sqlalchemy 是python sql工具包和对象关系映射器(orm),允许python开发者在应用程序中使用sql来交互,而无需处理数据库的具体细节
  • 提供一个高层的抽象层,允许开发者通过python类和对象来表示数据库中的表和行,从而使得数据库操作更加方便和灵活

二、核心(core)

sqlalchemy 的核心部分提供了一组工具来执行sql操作,包括创建和执行sql语句连接池管理事务管理等。开发者可以使用核心部分来执行一些高级的数据库操作,如自定义sql语句连接到数据库等。

三、优点

灵活性
多种不同的方式来与数据库交互,包括使用核心部分执行原始sql语句、使用orm进行对象关系映射、以及使用表达式语言构建sql查询等

功能丰富
许多功能丰富的工具和api,满足各种不同的数据库操作需求

orm支持
sqlalchemy 的orm工具允许开发者使用python类来代表数据库中的表和行,从而使得数据库操作更加pythonic和易于理解
orm工具提供了一种高级的抽象,隐藏了底层数据库操作的细节,使得开发者可以更专注于业务逻辑的实现

跨数据库支持
支持多种不同的数据库后端,包括mysql、postgresql、sqlite等

活跃的社区
sqlalchemy 有一个活跃的社区,提供了大量的文档、教程和示例代码,使得开发者可以更容易地学习和使用这个工具包

四、缺点性能开销

尽管sqlalchemy提供了许多便利的功能,但有时候这些功能可能会带来一定的性能开销。特别是在处理大量数据或需要高性能的场景下,可能需要仔细优化代码以减少性能损失

五、与其他工具比较

与其他orm工具的比较:

django ormpeeweesqlobject
与django orm相比,sqlalchemy提供了更多的灵活性和功能,尤其是在处理复杂数据库操作和跨数据库支持方面

但django orm更容易上手,并且与django框架无缝集成,适合快速开发和小型项目
peewee 是另一个轻量级的python orm工具,相比于sqlalchemy,它的学习曲线更为平缓,适合于简单的数据库操作和小型项目

但peewee的功能相对较少,不如sqlalchemy灵活
sqlobject 是另一个python orm库,它的设计更加接近于active record模式,与sqlalchemy的data mapper模式有所不同

但sqlobject的学习曲线较陡,且功能相对较少,通常适用于简单的数据库操作

2. 基本api

  • 安装库:pip install sqlalchemy
  • 验证是否安装成功:python -c "import sqlalchemy; print(sqlalchemy.__version__)" 或者 pip show sqlalchemy

在这里插入图片描述

为了让大家更快上手,先学习下下面这个实战项目:

from sqlalchemy import create_engine, column, integer, string
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建引擎
engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin')

# 创建session
session = sessionmaker(bind=engine)
session = session()

# 定义映射类
base = declarative_base()


class user(base):
    __tablename__ = 'manong'

    id = column(integer, primary_key=true)
    name = column(string(255))  # 在这里指定了 name 列的长度为 255
    age = column(integer)


# 创建表
base.metadata.create_all(engine)

# 插入数据
new_user = user(name='yanjiuseng', age=25)
session.add(new_user)
session.commit()

# 查询数据
query = session.query(user).filter(user.age > 18)
result = query.all()
for user in result:
    print(user.name, user.age)

最终截图如下:

在这里插入图片描述

通过看完整个代码逻辑,带着一些小疑问,深入探讨下这些api的使用方式

2.1 create_engine(创建引擎)

create_engine 函数用于创建一个与数据库的连接引擎,该引擎可以执行sql操作

from sqlalchemy import create_engine

engine = create_engine('mysql+pymysql://username:password@host:port/database')

针对里头的参数解释如下:

  • mysql:指定数据库类型,这里是 mysql 数据库
  • username:数据库用户名
  • password:数据库密码
  • host:数据库主机名或 ip 地址
  • port:数据库端口号,默认是 mysql 的端口号 3306
  • database:要连接的数据库名称

mysql 数据库用户名是 user1,密码是 pass123,主机名是 localhost,端口号是 3306,要连接的数据库名称是 my_database,那么连接字符串就应该是:

'mysql://user1:pass123@localhost:3306/my_database'

对于数据库类型常用的:mysql+pymysql,主要区别在于其使用的数据库驱动程序不同。

  • mysql+pymysql:(更简单地安装和使用,可以选择使用 pymysql
    指定使用 pymysql 作为连接 mysql 数据库的驱动程序,pymysql 是一个纯 python 实现的 mysql 客户端库,兼容 python 数据库 api 规范 2.0,可以在 python 中直接使用
  • mysql:(对性能要求比较高,可以选择使用 mysql 并配合 mysqldb 或者 mysqlclient
    没有指定具体的数据库驱动程序,使用默认的 mysql 客户端库,一般情况下会使用 mysqldb 或者 mysqlclient

再额外补充其他的url格式:

# mysql-python:
mysql+mysqldb://<user>:<password>@<host>:<port>/<dbname>

# pymysql:
mysql+pymysql://<username>:<password>@<host>:<port>/<dbname>?<options>

# mysql-connector:
mysql+mysqlconnector://<user>:<password>@<host>:<port>/<dbname>

# cx_oracle:
oracle+cx_oracle://<user>:<password>@<host>:<port>/<dbname>?key=value&key=value...

2.2 sessionmaker(创建session)

用于创建一个 session 类,该类用于执行 orm(对象关系映射)操作

主要作用是创建一个会话工厂,通过工厂可以创建数据库会话对象,用于在代码中执行数据库操作

# 创建session
session = sessionmaker(bind=engine)
session = session()

其中sessionmaker的参数如下:

  • bind:要绑定到的数据库引擎,通常是一个 create_engine 函数返回的 engine 对象
  • class_:可选参数,指定要创建的会话类,默认为 session 类
  • autocommit:是否自动提交事务,默认为 false
  • autoflush:是否自动刷新会话,默认为 true
  • expire_on_commit:在提交事务时是否自动使对象过期,默认为 true
  • info:一个字典,用于指定会话的其他配置信息

具体示例如下:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 创建引擎
engine = create_engine('sqlite:///example.db')

# 创建会话工厂
session = sessionmaker(bind=engine, autocommit=false, autoflush=true)

# 创建会话对象
session = session()

需要注意的点如下:

  • 在使用会话对象执行数据库操作后,一般需要调用 commit 方法提交事务,或者调用 rollback 方法回滚事务。
  • 在会话对象的作用域结束时,通常需要调用 close 方法关闭会话,释放数据库连接资源。

2.3 declarative_base(定义映射类)

使用 orm 进行数据库操作的核心部分之一,涉及到将数据库中的表映射到 python 中的类,以及定义类属性来表示表的列

一、映射类的定义

通过创建python 类来表示数据库中的表
该类通常继承自 sqlalchemy 的 base 类,而 base 类是使用 declarative_base() 函数创建的

from sqlalchemy.ext.declarative import declarative_base

base = declarative_base()

二、表的映射

在映射类中定义 __tablename__ 属性,指定该类所映射的数据库表的名称

class user(base):
    __tablename__ = 'users'

三、列的映射

在映射类中定义类属性,来表示表中的列

每个类属性通常都会被定义为 column 对象,并指定其数据类型以及其他属性

from sqlalchemy import column, integer, string

class user(base):
    __tablename__ = 'users'

    id = column(integer, primary_key=true)
    name = column(string(255))
    age = column(integer)

对应的属性如下:

属性的含义:

  • column:表示一个数据库表的列
  • integerstring 等数据类型:表示列的数据类型
  • primary_key=true:指定该列为主键

其他参数:例如长度、唯一性等,用于进一步定义列的属性

2.4 sql与orm差异

一、基于 sql 的查询:

特点:

原始的 sql 查询语句,手动编写 sql 语句来执行数据库操作。于执行复杂的查询、跨表查询或性能要求较高的场景

示例代码:

from sqlalchemy import create_engine, text

# 创建引擎
engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin')

# 执行 sql 查询
with engine.connect() as connection:
    result = connection.execute(text("select * from manong where age > :age"), {'age': 18})
    for row in result:
        print(row)

截图如下:

在这里插入图片描述

二、基于orm查询

  • 操作对象来执行数据库操作,而不需要编写原始的 sql 语句
  • 提供了更加 pythonic 和面向对象的接口,使得代码更加清晰和易于维护
from sqlalchemy import create_engine, column, integer, string
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建引擎
engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin')

# 创建session
session = sessionmaker(bind=engine)
session = session()

# 定义映射类
base = declarative_base()


class user(base):
    __tablename__ = 'manong'

    id = column(integer, primary_key=true)
    name = column(string(255))  # 在这里指定了 name 列的长度为 255
    age = column(integer)

result = session.query(user).filter(user.age > 18).all()
for user in result:
    print(user.name, user.age)

区别的方式在于:

  • 实现方式:基于 sql 的查询直接使用原始的 sql 语句,而基于 orm 的查询则是通过 orm 工具来执行数据库操作
  • 编写方式:基于 sql 的查询需要开发者手动编写 sql 语句,而基于 orm 的查询则是通过操作对象来执行数据库操作,不需要编写原始的 sql 语句
  • 灵活性:基于 sql 的查询更加灵活,可以执行复杂的原始 sql 查询,而基于 orm 的查询提供了更加 pythonic 和面向对象的接口,使得代码更加清晰和易于维护

3. orm crud

对于基本的sql查询,需要编写sql语句,此处偏向实战类,所以详细补充orm crud的的基本知识

前半部分代码如下:

from sqlalchemy import create_engine, column, integer, string
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 创建引擎
engine = create_engine('mysql+pymysql://root:root@127.0.0.1:3306/easy-admin')

# 创建session
session = sessionmaker(bind=engine)
session = session()

# 定义映射类
base = declarative_base()


class user(base):
    __tablename__ = 'manong'

    id = column(integer, primary_key=true)
    name = column(string(255))  # 在这里指定了 name 列的长度为 255
    age = column(integer)

# 创建表
base.metadata.create_all(engine)

3.1 增加(c)

  • 添加单个对象:将新对象添加到数据库中
user = user(name='aa', age=30)
session.add(user)
session.commit()
  • 添加多个对象:将多个新对象批量添加到数据库中
users = [user(name='bb', age=30), user(name='cc', age=25)]
session.add_all(users)
session.commit()

3.2 查找(r)

查询所有对象:从数据库中检索所有对象

all_users = session.query(user).all()

根据条件查询:根据指定条件过滤对象

# # 查询数据
result = session.query(user).filter(user.age > 18).all()
for user in result:
    print(user.name, user.age)

查询单个对象:从数据库中检索满足条件的单个对象

user = session.query(user).filter_by(name='alice').first()

3.3 更新(u)

更新单个对象:修改数据库中的现有对象

user = session.query(user).filter_by(name='alice').first()
user.age = 35
session.commit()

批量更新:使用 update() 方法批量更新满足条件的对象

session.query(user).filter(user.age < 30).update({'age': 30})
session.commit()

3.4 删除(d)

删除单个对象:从数据库中删除指定的对象

user = session.query(user).filter_by(name='alice').first()
session.delete(user)
session.commit()

批量删除:使用 delete() 方法批量删除满足条件的对象

session.query(user).filter(user.age > 30).delete()
session.commit()

4. 彩蛋

4.1 建表bug

建表的过程中如果语句如下:

class manong(base):
    __tablename__ = 'manong'

    id = column(integer)
    name = column(string)

报错信息如下: sqlalchemy.exc.compileerror: (in table 'manong', column 'name'): varchar requires a length on dialect mysql

主要问题如下:
在 mysql 中,varchar 类型的列必须指定长度,即字符的最大数量。
需要为表中的 varchar 类型的列指定长度

将其代码修改为:

from sqlalchemy import column, integer, string
from sqlalchemy.ext.declarative import declarative_base

base = declarative_base()

class manong(base):
    __tablename__ = 'manong'

    id = column(integer, primary_key=true)
    name = column(string(255))  # 在这里指定了 name 列的长度为 255

# 继续定义其他列和表结构

如果不是建表,可以省略字段长度

4.2 filter 和 filter_by

  • filter 方法使用类名和属性名来构建查询条件,比较通常使用 ==,也可以使用其他比较操作符如 ><>=<= 等
  • filter_by 方法直接使用属性名和相应的值来构建查询条件,比较通常使用 =

以下为简易demo,方便理解:

# 使用 filter 方法
from sqlalchemy.orm import sessionmaker

session = sessionmaker(bind=engine)
session = session()

# 查询名字为 alice 的记录
alice_records = session.query(user).filter(user.name == 'alice').all()

# 查询年龄大于等于 25 岁的记录
older_users = session.query(user).filter(user.age >= 25).all()

# 使用 filter_by 方法
# 查询名字为 alice 的记录
alice_records = session.query(user).filter_by(name='alice').all()

filter 的组合查询: (这个在实战中比较常用!!!)

通过连续调用来实现多个条件的组合查询,或者使用and 条件连接多个条件

# 使用 filter 连续添加条件查询
# 查询名字为 alice 且年龄大于等于 25 岁的记录
alice_older_records = session.query(user).filter(user.name == 'alice').filter(user.age >= 25).all()

或者如下:

from sqlalchemy import and_

# 使用 and_ 函数连接两个条件
alice_older_records = session.query(user).filter(and_(user.name == 'alice', user.age >= 25)).all()

以上就是python中sqlalchemy库的使用方法分析的详细内容,更多关于python sqlalchemy库使用的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com