SQLAlchemy

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 类与数据库表结构建立映射关系。

 添加记录

然后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.mzph.cn/web/65805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Trimble自动化激光监测支持历史遗产实现可持续发展【沪敖3D】

故事桥(Story Bridge)位于澳大利亚布里斯班,建造于1940年,全长777米,横跨布里斯班河,可载汽车、自行车和行人往返于布里斯班的北部和南部郊区。故事桥是澳大利亚最长的悬臂桥,是全世界两座手工建…

CentOS 和 Ubantu你该用哪个

文章目录 **一、CentOS 和 Ubuntu 的详细介绍****1. CentOS****1.1 基本信息****1.2 特点****1.3 缺点** **2. Ubuntu****2.1 基本信息****2.2 特点****2.3 缺点** **二、CentOS 和 Ubuntu 的异同****1. 相同点****2. 不同点****3. 使用体验对比** **三、总结和选择建议** Cent…

Android RIL(Radio Interface Layer)全面概述和知识要点(3万字长文)

在Android面试时,懂得越多越深android framework的知识,越为自己加分。 目录 第一章:RIL 概述 1.1 RIL 的定义与作用 1.2 RIL 的发展历程 1.3 RIL 与 Android 系统的关系 第二章:RIL 的架构与工作原理 2.1 RIL 的架构组成 2.2 RIL 的工作原理 2.3 RIL 的接口与协议…

前端学习-事件对象与典型案例(二十六)

目录 前言 事件对象 目标 事件对象是什么 语法 获取事件对象 部分常用属性 示例代码 示例代码:评论回车发布 总结 前言 长风破浪会有时,直挂云帆济沧海。 事件对象 目标 能说出什么是事件对象 事件对象是什么 也是个对象,这个对…

Playwright vs Selenium:全面对比分析

在现代软件开发中,自动化测试工具在保证应用质量和加快开发周期方面发挥着至关重要的作用。Selenium 作为自动化测试领域的老牌工具,长期以来被广泛使用。而近年来,Playwright 作为新兴工具迅速崛起,吸引了众多开发者的关注。那么…

Windows 程序设计3:宽窄字节的区别及重要性

文章目录 前言一、宽窄字节简介二、操作系统及VS编译器对宽窄字节的编码支持1. 操作系统2. 编译器 三、宽窄字符串的优缺点四、宽窄字节数据类型总结 前言 Windows 程序设计3:宽窄字节的区别及重要性。 一、宽窄字节简介 在C中,常用的字符串指针就是ch…

进阶——十六届蓝桥杯嵌入式熟练度练习(LED的全开,全闭,点亮指定灯,交替闪烁,PWM控制LED呼吸灯)

点亮灯的函数 void led_show(unsigned char upled) { HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,upled<<8,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RE…

力扣 最大子数组和

动态规划&#xff0c;前缀和&#xff0c;维护状态更新。 题目 从题可以看出&#xff0c;找的是最大和的连续子数组&#xff0c;即一个数组中的其中一个连续部分。从前往后遍历&#xff0c;每遍历到一个数可以尝试做叠加&#xff0c;注意是尝试&#xff0c;因为有可能会遇到一个…

Homestyler 和 Tripo AI 如何利用人工智能驱动的 3D 建模改变定制室内设计

让设计梦想照进现实 在Homestyler,我们致力于为每一个梦想设计师提供灵感的源泉,而非挫折。无论是初学者打造第一套公寓,或是专业设计师展示作品集,我们的直观工具都能让您轻松以惊人的3D形式呈现空间。 挑战:实现定制设计的新纪元 我们知道,将个人物品如传家宝椅子、…

如何当前正在运行的 Elasticsearch 集群信息

要查看当前正在运行的 Elasticsearch 集群信息&#xff0c;可以通过以下几种方法&#xff1a; 1. 使用 _cluster/health API _cluster/health API 返回集群的健康状态、节点数量、分片状态等信息。可以用 curl 命令直接访问&#xff1a; curl -X GET "http://localhost…

算法练习4——一个六位数

这道题特别妙 大家仔细做一做 我这里采用的是动态规划来解这道题 结合题目要求找出数与数之间的规律 抽象出状态转移方程 题目描述 有一个六位数&#xff0c;其个位数字 7 &#xff0c;现将个位数字移至首位&#xff08;十万位&#xff09;&#xff0c;而其余各位数字顺序不…

client-go 的 QPS 和 Burst 限速

1. 什么是 QPS 和 Burst &#xff1f; 在 kubernetes client-go 中&#xff0c;QPS 和 Burst 是用于控制客户端与 Kubernetes API 交互速率的两个关键参数&#xff1a; QPS (Queries Per Second) 定义&#xff1a;表示每秒允许发送的请求数量&#xff0c;即限速器的平滑速率…

B-tree 数据结构详解

1. 引言 1.1 什么是 B-tree&#xff1f; B-tree&#xff08;Balanced Tree&#xff0c;平衡树&#xff09;是一种自平衡的多路搜索树数据结构&#xff0c;其核心特性包括&#xff1a; 多路性&#xff1a; 每个节点可以包含多个关键字和子节点&#xff0c;而非仅二分。平衡性…

Python 正则表达式完全指南

# Python 正则表达式完全指南 正则表达式&#xff08;Regular Expression&#xff09;是Python中进行文本处理的强大工具。本指南将详细介绍Python中正则表达式的使用方法和实践技巧。 ## 1. 基础知识 ### 1.1 导入正则表达式模块 python import re ### 1.2 创建正则表达式 在…

Vue的scoped原理是什么

CSS常见模块化方案 BEM&#xff08;Block Element Modifier&#xff09;: BEM是一种流行的命名约定&#xff0c;它通过特定的命名规则来组织CSS类名&#xff0c;使得样式具有模块化、可重用性和可读性。BEM的命名规则是&#xff1a;block__element--modifier。 block&#xf…

【LC】3270. 求出数字答案

题目描述&#xff1a; 给你三个 正 整数 num1 &#xff0c;num2 和 num3 。 数字 num1 &#xff0c;num2 和 num3 的数字答案 key 是一个四位数&#xff0c;定义如下&#xff1a; 一开始&#xff0c;如果有数字 少于 四位数&#xff0c;给它补 前导 0 。答案 key 的第 i 个数…

太原理工大学软件设计与体系结构 --javaEE

这个是简答题的内容 选择题的一些老师会给你们题库&#xff0c;一些注意的点我会做出文档在这个网址 项目目录预览 - TYUT复习资料:复习资料 - GitCode 希望大家可以给我一些打赏 什么是Spring的IOC和DI IOC 是一种设计思想&#xff0c;它将对象的创建和对象之间的依赖关系…

深度学习知识点:LSTM

文章目录 1.应用现状2.发展历史3.基本结构4.LSTM和RNN的差异 1.应用现状 长短期记忆神经网络&#xff08;LSTM&#xff09;是一种特殊的循环神经网络(RNN)。原始的RNN在训练中&#xff0c;随着训练时间的加长以及网络层数的增多&#xff0c;很容易出现梯度爆炸或者梯度消失的问…

mmdet

一&#xff0c;configs/_base_ 1.default_runtime.py 2.schedule_1x.py 二&#xff0c;mmdet 1.datasets/coco.py/CocoDataset METAINFO {classes:(milk, red, spring, fanta, sprite, pepsi, king, ice, cola, scream ),# palette is a list of color tuples, which is us…

ElasticSearch 认识和安装ES

文章目录 一、为什么学ElasticSearch?1.ElasticSearch 简介2.ElasticSearch 与传统数据库的对比3.ElasticSearch 应用场景4.ElasticSearch 技术特点5.ElasticSearch 市场表现6.ElasticSearch 的发展 二、认识和安装ES1.认识 Elasticsearch&#xff08;简称 ES&#xff09;2.El…