SQLAlchemy从入门到进阶 | python 小知识
一、对象关系映射(ORM)简介
对象关系映射(Object-Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。
对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。
通俗来讲,ORM的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。
二、SQLAlchemy简介
SQLAlchemy是Python编程语言下的一款开源软件,它提供了SQL工具包及对象关系映射(ORM)工具,使用MIT许可证发行。SQLAlchemy首次发行于2006年2月,并迅速在Python社区中成为广泛使用的ORM工具之一。
SQLAlchemy的主要功能包括:
- ORM(Object-Relational Mapping):SQLAlchemy提供了ORM功能,可以将数据库中的表映射到Python对象,使得开发人员能够通过操作Python对象来实现对数据库的增删改查操作,而无需直接编写SQL语句。这种ORM映射可以提高开发效率并降低数据库相关代码的复杂度。
- 数据库连接管理:SQLAlchemy提供了统一的数据库连接管理,支持各种流行的关系型数据库,如MySQL、PostgreSQL、SQLite、Oracle等,开发人员可以使用一套相似的接口来连接和操作不同的数据库。
- 事务管理:SQLAlchemy支持数据库事务的管理,确保数据库操作的一致性和可靠性。它允许以更安全的方式执行事务,确保在出现错误或异常时能够正确回滚或提交事务。
- 灵活的查询语言:SQLAlchemy提供了灵活且强大的查询语言,允许构建复杂的SQL查询,同时也支持更高级别的查询,例如联结、子查询、聚合函数等。
- 跨平台支持:由于SQLAlchemy是一个Python库,它能够在各种平台上运行,不受特定数据库平台的限制。
SQLAlchemy被广泛应用于Web开发、数据分析以及其他需要与数据库交互的场景。
三、SQLAlchemy入门
3.1 安装SQLAlchemy
在开始使用SQLAlchemy之前,我们需要将其安装到系统中。安装过程可以通过Python的包管理工具pip轻松完成。打开终端或命令提示符,输入以下命令来安装SQLAlchemy:
pip install sqlalchemy
3.2 ORM基础
SQLAlchemy通过ORM技术,将数据库表映射为Python类,将表中的行映射为类的实例,将列映射为实例的属性。
以下是一个简单的例子,展示了如何使用SQLAlchemy定义一个数据库模型,并创建相应的数据库表:
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
# 创建数据库引擎(连接数据库的过程)
engine = create_engine(sqlite:///example.db)
# 定义模型基类
Base = declarative_base()
# 定义User类,映射到数据库中的users表
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String)
fullname = Column(String)
# 根据设置的信息创建数据库表
Base.metadata.create_all(engine)
在上面的代码中,我们定义了一个User
类,并将其映射到数据库中的users
表。每个类的属性对应表中的一列,而类本身则对应一个表。
3.3 数据库操作
Session是SQLAlchemy中用于执行数据库操作的对象。它代表了一个到数据库的临时会话,可以进行数据的查询、插入、更新和删除操作。
以下是一个使用Session进行数据库操作的例子:
from sqlalchemy.orm import sessionmaker
# 创建Session类
Session = sessionmaker(bind=engine)
# 创建Session对象
session = Session()
# 添加数据
user1 = User(name='John Doe', fullname='John Doe Smith')
session.add(user1)
session.commit() # 提交事务
# 查询数据
for user in session.query(User).all():
print(fid: {user.id}, name: {user.name}, fullname: {user.fullname})
# 更新数据
user1.name = 'John Smith'
session.commit() # 提交事务
# 删除数据
session.delete(user1)
session.commit() # 提交事务
在上面的代码中,我们首先创建了一个Session对象,然后使用它进行数据的添加、查询、更新和删除操作。每次操作后,都需要调用commit()
方法来提交事务。
四、SQLAlchemy进阶
4.1 复杂查询
SQLAlchemy提供了灵活且强大的查询语言,允许构建复杂的SQL查询。以下是一个使用SQLAlchemy进行复杂查询的例子:
# 查询name为'John Doe'的用户
user = session.query(User).filter_by(name='John Doe').first()
print(fUser found: {user.name}, {user.fullname})
# 使用聚合函数查询用户数量
from sqlalchemy import func
user_count = session.query(func.count(User.id)).scalar()
print(fTotal users: {user_count})
在上面的代码中,我们首先使用filter_by()
方法进行条件查询,然后使用first()
方法获取查询结果的第一条记录。接着,我们使用func.count()
聚合函数查询用户数量,并使用scalar()
方法获取查询结果的单个值。
4.2 定义关系映射
SQLAlchemy支持在数据模型之间建立关系,这使得可以关联不同表的数据。通过定义关系映射,可以实现一对多、多对多等复杂的数据关系。
以下是一个定义多对多关系的例子:
from sqlalchemy import Table, ForeignKey, Column, Integer, String
from sqlalchemy.orm import relationship
# 定义关联表
user_role = Table('user_role', Base.metadata,
Column('user_id', Integer, ForeignKey('user.id'), primary_key=True),
Column('role_id', Integer, ForeignKey('role.id'), primary_key=True)
)
# 定义用户表
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(50), unique=True)
roles = relationship(Role, secondary=user_role, back_populates=users)
# 定义角色表
class Role(Base):
__tablename__ = 'role'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), unique=True)
users = relationship(User, secondary=user_role, back_populates=roles)
# 创建表
Base.metadata.create_all(engine)
# 插入数据并关联用户和角色
with Session(engine) as session:
user1 = User(username=zhangsan)
user2 = User(username=lisi)
role1 = Role(name=管理员)
role2 = Role(name=编辑)
user1.roles.append(role1)
user1.roles.append(role2)
user2.roles.append(role1)
session.add_all([user1, user2, role1, role2])
session.commit()
# 查询并打印数据
with Session(engine) as session:
users = session.query(User).all()
for user in users:
print(f用户: {user.username})
for role in user.roles:
print(f 角色: {role.name})
在上面的代码中,我们首先定义了一个关联表user_role
,用于存储用户和角色之间的多对多关系。然后,我们定义了User
和Role
两个类,并在它们之间建立了关系。接着,我们使用Session对象插入数据并关联用户和角色。最后,我们查询并打印了用户和角色的信息。
通过以上内容,我们了解了SQLAlchemy的基本概念和主要功能,并通过代码示例展示了如何使用SQLAlchemy进行数据库操作。希望这篇blog能够帮助你更好地理解和使用SQLAlchemy。