SQLAlchemy

ops/2025/1/17 2:14:31/

目录

https://docs.sqlalchemy.org.cn/en/20/orm/quickstart.htmlhttps://docs.sqlalchemy.org.cn/en/20/orm/quickstart.html

声明模型¶

 SQLAlchemy 2.0

 安装

 连接数据库

​编辑 映射类

​编辑 查询

 修改记录

 一对多的映射

多对多的映射

一对一的映射


https://docs.sqlalchemy.org.cn/en/20/orm/quickstart.htmlicon-default.png?t=O83Ahttps://docs.sqlalchemy.org.cn/en/20/orm/quickstart.html

声明模型¶

在这里,我们定义模块级构造,这些构造将构成我们从数据库中查询的结构。这种结构被称为 声明式映射,它同时定义了 Python 对象模型以及 数据库元数据,该元数据描述了在特定数据库中存在或将存在的实际 SQL 表。

Base = declarative_base() 是 SQLAlchemy 中的一个关键语句,它用于定义一个基础类(Base),所有 ORM 模型类都需要继承这个基础类。通过这种方式,SQLAlchemy 能够将 Python 类与数据库表结构建立映射关系。

from sqlalchemy.ext.declarative import declarative_base# 创建基础类
Base = declarative_base()

实例代码 

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker# 创建基础类
Base = declarative_base()# 定义 ORM 模型类
class User(Base):__tablename__ = 'users'  # 映射到数据库中的表名id = Column(Integer, primary_key=True)  # 定义主键name = Column(String(50))  # 定义列age = Column(Integer)# 创建数据库引擎
engine = create_engine('sqlite:///:memory:')# 创建所有表
Base.metadata.create_all(engine)# 创建会话
Session = sessionmaker(bind=engine)
session = Session()# 插入数据
new_user = User(name='Alice', age=25)
session.add(new_user)
session.commit()# 查询数据
user = session.query(User).filter_by(name='Alice').first()
print(user.name, user.age)  # 输出: Alice 25

 直接执行就可以创建表了

SQLAlchemy 2.0

 SQLAlchemy 2.0 或更高版本,建议采用这种新形式来定义 ORM 模型类。

这是新版本的

class User(Base):__tablename__ = "user_account"id: Mapped[int] = mapped_column(primary_key=True)name: Mapped[str] = mapped_column(String(30))fullname: Mapped[Optional[str]]addresses: Mapped[List["Address"]] = relationship(back_populates="user", cascade="all, delete-orphan")

 这个是旧版本的

Base = declarative_base()# Step 3. 定义可以使用Base类管理的模型类
class Session(Base):"""Session 类表示聊天会话"""__tablename__ = "sessions"id = Column(Integer, primary_key=True)## unique=True表示 session_id 字段的值必须是唯一的,不能有重复值。 不能为空session_id = Column(String, unique=True, nullable=False)# 这不是数据库中的一个具体字段,而是 ORM 层面的逻辑关系,用于简化操作和查询。messages = relationship("Message", back_populates="session")class Message(Base):"""Message 类表示会话中的各个消息"""__tablename__ = "messages"id = Column(Integer, primary_key=True)session_id = Column(Integer, ForeignKey("sessions.id"), nullable=False)role = Column(String, nullable=False)content = Column(Text, nullable=False)session = relationship("Session", back_populates="messages")

 安装

 

 连接数据库

 映射类

Base = declarative_base() 是 SQLAlchemy 中的一个关键语句,它用于定义一个基础类(Base),所有 ORM 模型类都需要继承这个基础类。通过这种方式,SQLAlchemy 能够将 Python 类与数据库表结构建立映射关系。

写好模型类后只需要 Base.metadata.create_all 就可以创建所以继承base类的表

 通过session进行管理,绑定数据库引擎

 添加记录

然后session.commit() 

 查询

session = Session()# result = session.query(Person).all()
result = session.query(Person).filter(Person.address == 'aaa')for person in result:print(f'name: {person.name}, birthday: {person.birthday}')

# person = session.query(Person).filter(Person.address == 'aaa').first()
# person = session.query(Person).filter(Person.id == 100).first()
# person = session.query(Person).filter(Person.id == 1).one()
# 返回查询结果的第一条记录的第一列值。
person = session.query(Person).filter(Person.id == 1).scalar()

 修改记录

记得提交事务

方式2修改时要传json的表达式

新的映射

class User(Base):__tablename__ = "user_account"id: Mapped[int] = mapped_column(primary_key=True)name: Mapped[str] = mapped_column(String(30))fullname: Mapped[Optional[str]]addresses: Mapped[List["Address"]] = relationship(back_populates="user", cascade="all, delete-orphan")

 当一些字段重复是可以单独定义出来

import datetimefrom sqlalchemy import create_engine, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Mapped, mapped_column
from sqlalchemy.sql import func
from typing_extensions import Annotatedengine = create_engine('mysql://root:test@localhost/testdb', echo=True)
Base = declarative_base()# 当很多字段都有统一的要求,就把他给单独定义出来
int_pk = Annotated[int, mapped_column(primary_key=True)]
required_unique_name = Annotated[str, mapped_column(String(128), unique=True, nullable=False)]
timestamp_default_now = Annotated[datetime.datetime, mapped_column(nullable=False, server_default=func.now())]class Customer(Base):__tablename__ = "customers"id: Mapped[int_pk]name: Mapped[required_unique_name]birthday: Mapped[datetime.datetime]city: Mapped[str] = mapped_column(String(128), nullable=True)create_time: Mapped[timestamp_default_now]Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

 一对多的映射

一开始没relationship

class Department(Base):__tablename__ = "department"id: Mapped[int_pk]name: Mapped[required_unique_name]def __repr__(self):return f'id: {self.id}, name: {self.name}'class Employee(Base):__tablename__ = "employee"id: Mapped[int_pk]dep_id: Mapped[int] = mapped_column(ForeignKey("department.id"))name: Mapped[required_unique_name]birthday: Mapped[timestamp_not_null]

 这样会出错,因为对象还没真正存入数据库,所以主键id就没生成,可以采用 flush() 刷新进去,但是多了之后不知道哪里需要flush(),所以有了relationship

单纯加上relationship这个就好,并且可以直接查看关联的部门信息

class Department(Base):__tablename__ = "department"id: Mapped[int_pk]name: Mapped[required_unique_name]def __repr__(self):return f'id: {self.id}, name: {self.name}'class Employee(Base):__tablename__ = "employee"id: Mapped[int_pk]dep_id: Mapped[int] = mapped_column(ForeignKey("department.id"))name: Mapped[required_unique_name]birthday: Mapped[timestamp_not_null]department: Mapped[Department] = relationship()

 只加员工对象就可以,他会直接把部门对象也创建出来,依据有没有id判断是存在 还是不存在,

不存在就会创建

 并且可以直接查看部门信息

import datetimefrom sqlalchemy import create_engine, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Mapped, mapped_column, relationship
from typing_extensions import Annotated
from typing import Listengine = create_engine('mysql://root:test@localhost/testdb', echo=True)
Base = declarative_base()int_pk = Annotated[int, mapped_column(primary_key=True)]
required_unique_name = Annotated[str, mapped_column(String(128), unique=True, nullable=False)]
timestamp_not_null = Annotated[datetime.datetime, mapped_column(nullable=False)]class Department(Base):__tablename__ = "department"id: Mapped[int_pk]name: Mapped[required_unique_name]# 显式的表示出来employees: Mapped[List["Employee"]] = relationship(back_populates="department")def __repr__(self):return f'id: {self.id}, name: {self.name}'class Employee(Base):__tablename__ = "employee"id: Mapped[int_pk]dep_id: Mapped[int] = mapped_column(ForeignKey("department.id"))name: Mapped[required_unique_name]birthday: Mapped[timestamp_not_null]# relationship 实际不存在表中,他只存在内存中,lazy=False表示取消懒加载 ,查询的时候直接把另一个给查出来# back_populates="employees"  自动给department表增加一个映射employees,而且他是一个集合类型的 这个employees当前对应的就是这个表# 这个映射在department你看不见,但是为了可读性直观一些,我们会显式的表示出来# 这样定义完之后,我们就可以直接查看部分的信息了department: Mapped[Department] = relationship(lazy=False, back_populates="employees")def __repr__(self):return f'id: {self.id}, dep_id: {self.dep_id}, name: {self.name}, birthday: {self.birthday}'Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)

多对多的映射

并不需要专门定义一个类,如果专门定义一个类,那么就成为了多个一对多的映射

这是联合主键

import datetimefrom sqlalchemy import create_engine, String, ForeignKey, Table, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Mapped, mapped_column, relationship
from typing_extensions import Annotated
from typing import List, Setengine = create_engine('mysql://root:test@localhost/testdb', echo=True)
Base = declarative_base()int_pk = Annotated[int, mapped_column(primary_key=True)]
required_unique_name = Annotated[str, mapped_column(String(128), unique=True, nullable=False)]
required_string = Annotated[str, mapped_column(String(128), nullable=False)]# 多对多的中间表,不用声明一个类
# 这是联合主键
association_table = Table("user_role",Base.metadata,Column("user_id", ForeignKey("users.id"), primary_key=True),Column("role_id", ForeignKey("roles.id"), primary_key=True)
)class User(Base):__tablename__ = "users"id: Mapped[int_pk]name: Mapped[required_unique_name]password: Mapped[required_string]# secondary=association_table 指明中间表roles: Mapped[List["Role"]] = relationship(secondary=association_table, lazy=False, back_populates="users")def __repr__(self):return f'id: {self.id}, name: {self.name}'class Role(Base):__tablename__ = "roles"id: Mapped[int_pk]name: Mapped[required_unique_name]users: Mapped[List["User"]] = relationship(secondary=association_table, lazy=True, back_populates="roles")def __repr__(self):return f'id: {self.id}, name: {self.name}'Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
from db_init import Session, User, Roledef insert_records(s):role1 = Role(name="Admin")role2 = Role(name="Operator")user1 = User(name="Jack", password="111")user2 = User(name="Tom", password="222")user3 = User(name="Mary", password="333")# 用户中添加角色user1.roles.append(role1)user1.roles.append(role2)user2.roles.append(role1)user3.roles.append(role2)s.add_all([user1, user2, user3])s.commit()def select_user(s):u = s.query(User).filter(User.id == 1).one()print(u)print(u.roles)def select_role(s):r = s.query(Role).filter(Role.id == 2).one()print(r)print(r.users)session = Session()
# insert_records(session)
# select_user(session)
select_role(session)

一对一的映射

import datetimefrom sqlalchemy import create_engine, String, ForeignKey, Table, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Mapped, mapped_column, relationship
from typing_extensions import Annotated
from typing import List, Setengine = create_engine('mysql://root:test@localhost/testdb', echo=True)
Base = declarative_base()int_pk = Annotated[int, mapped_column(primary_key=True)]
required_unique_string = Annotated[str, mapped_column(String(128), unique=True, nullable=False)]
required_string = Annotated[str, mapped_column(String(128), nullable=False)]class Employee(Base):__tablename__ = "employee"id: Mapped[int_pk]name: Mapped[required_unique_string]computer_id: Mapped[int] = mapped_column(ForeignKey("computer.id"), nullable=True)computer = relationship("Computer", lazy=False, back_populates="employee")def __repr__(self):return f'id: {self.id}, name: {self.name}'class Computer(Base):__tablename__ = "computer"id: Mapped[int_pk]model: Mapped[required_string]number: Mapped[required_unique_string]employee = relationship("Employee", lazy=True, back_populates="computer")def __repr__(self):return f'id: {self.id}, model: {self.model}, number: {self.number}'Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
from db_init import Session, Employee, Computerdef insert(s):c1 = Computer(model="Dell", number="1111")c2 = Computer(model="Surface", number="2222")c3 = Computer(model="MacBook Pro", number="3333")e1 = Employee(name="Jack", computer=c1)e2 = Employee(name="Mary", computer=c2)e3 = Employee(name="Tome", computer=c3)s.add_all([e1, e2, e3])s.commit()def select(s):e = s.query(Employee).filter(Employee.id == 1).scalar()if e:print(e)print(e.computer)c = s.query(Computer).filter(Computer.id == 2).scalar()if c:print(c)print(c.employee)def update_1(s):s.query(Employee).filter(Employee.id == 3).update({Employee.computer_id: None})s.commit()def update_2(s):c = s.query(Computer).filter(Computer.id == 3).scalar()e = s.query(Employee).filter(Employee.id == 3).scalar()if c and e:e.computer = cs.commit()session = Session()
# insert(session)
# select(session)
# update_1(session)
update_2(session)


http://www.ppmy.cn/ops/150691.html

相关文章

什么是数据仓库?

什么是数据仓库? 数据仓库(Data Warehouse,简称DW)是一种面向分析和决策的数据存储系统,它将企业中分散的、异构的数据按照一定的主题和模型进行集成和存储,为数据分析、报表生成以及商业智能(…

宜自动化处理的五件事

自动化技术宛如一把神奇的钥匙,能够开启便捷之门,解锁诸多潜能。以下详细阐述适宜采用自动化处理的五件事,助力各方在各自领域快人一步。 一、数据录入与整理 无论是企业的财务报表、销售数据,还是科研机构的实验记录&#xff0…

通义文生视频模型升级,天工推理模型正式上线,微软开源小模型Phi-4!AI Weekly『1月6-1月12日』

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

【Go】Go Gin框架初识(一)

1. 什么是Gin框架 Gin框架:是一个由 Golang 语言开发的 web 框架,能够极大提高开发 web 应用的效率! 1.1 什么是web框架 web框架体系图(前后端不分离)如下图所示: 从上图中我们可以发现一个Web框架最重要…

基于YOLOv8与CGNet的鸟类智能识别系统 深度学习图像分类 鸟类目标检测与分类 图像特征提取 模型优化与应用 数据可视化(源码+指导+定制)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

科技快讯 | 抖音治理AI造假地震图片;投影仪也玩三折叠;京东发布“AI京医”大模型

智谱 GLM 大模型在模型幻觉排行榜中居首,事实一致性达 98.7% 近日,智谱旗下GLM-4-9B模型在HHEM-2.1-Open幻觉评估模型排行榜中,以1.3%的幻觉率排名第一,超越了OpenAI的GPT系列和Google的Gemini系列等世界顶尖模型。信息来源于智谱…

C#中的Span

一、引言 在 C# 开发的广袤天地里,性能犹如一把高悬的达摩克利斯之剑,时刻影响着应用程序的质量与用户体验。从响应迟缓的界面交互,到耗时良久的数据处理,性能瓶颈如同顽疾,阻碍着软件的高效运行。无论是追求极致流畅…

PyCharm文档管理

背景:使用PyCharmgit做文档管理 需求:需要PyCharm自动识别docx/xslx/vsdx等文件类型,并在PyCharm内点击文档时唤起系统内关联应用(如word、excel、visio) 设置步骤: 1、file -》 settings -》file types 2、在Files opened i…