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米,横跨布里斯班河,可载汽车、自行车和行人往返于布里斯班的北部和南部郊区。故事桥是澳大利亚最长的悬臂桥,是全世界两座手工建…

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形式呈现空间。 挑战:实现定制设计的新纪元 我们知道,将个人物品如传家宝椅子、…

算法练习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;即限速器的平滑速率…

太原理工大学软件设计与体系结构 --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…

第34天:安全开发-JavaEE应用反射机制攻击链类对象成员变量方法构造方法

时间轴&#xff1a; Java反射相关类图解&#xff1a; 反射&#xff1a; 1、什么是 Java 反射 参考&#xff1a; https://xz.aliyun.com/t/9117 Java 提供了一套反射 API &#xff0c;该 API 由 Class 类与 java.lang.reflect 类库组成。 该类库包含了 Field 、 Me…

汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2)

汽车基础软件AutoSAR自学攻略(三)-AutoSAR CP分层架构(2) 下面我们继续来介绍AutoSAR CP分层架构&#xff0c;下面的文字和图来自AutoSAR官网目前最新的标准R24-11的分层架构手册。该手册详细讲解了AutoSAR分层架构的设计&#xff0c;下面让我们来一起学习一下。 Introductio…

css面试常考布局(圣杯布局、双飞翼布局、三栏布局、两栏布局、三角形)

两栏布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

网络攻击行为可视化分析系统【数据分析 + 可视化】

一、系统背景 随着信息技术的快速发展&#xff0c;网络已成为现代社会不可或缺的一部分。然而&#xff0c;与此同时&#xff0c;网络攻击手段也日益多样化和复杂化&#xff0c;给企业和个人的信息安全带来了极大的威胁。传统的网络攻击分析方法往往依赖于人工分析和处理大量的…

利用obs studio制作(人像+屏幕)录制影像

1.什么是obs? OBS&#xff08;Open Broadcaster Software&#xff09;是一款功能强大的开源软件&#xff0c;它使用户能够直接从电脑录制视频和直播内容到 Twitch&#xff0c;YouTube 和 Facebook Live 等平台。它在需要直播或录制屏幕活动的游戏玩家、YouTube 用户和专业人士…

C# GDI+的DrawString无法绘制Tab键的现象

【啰嗦2句】 现在用C#的人很少了吧&#xff1f;GDI更少了吧&#xff1f;所以这个问题估计也冷门。没关系&#xff0c;分享给特定需要的人也不错。 【问题现象】 工作中开发了一个报告编辑器&#xff0c;实现图文排版等功能&#xff0c;用着没什么问题&#xff0c;直到有一天…

夯实前端基础之HTML篇

知识点概览 HTML部分 1. DOM和BOM有什么区别&#xff1f; DOM&#xff08;Document Object Model&#xff09; 当网页被加载时&#xff0c;浏览器会创建页面的对象文档模型&#xff0c;HTML DOM 模型被结构化为对象树 用途&#xff1a; 主要用于网页内容的动态修改和交互&…

SD ComfyUI工作流 老照片修复上色

文章目录 老照片修复上色SD模型Node节点工作流程开发与应用效果展示老照片修复上色 该工作流专门设计用于老照片的修复和上色,通过一系列高级的图像处理技术,包括深度图预处理、面部修复、上色和图像放大等步骤,来恢复老照片的质量并增加色彩。首先,工作流加载老照片并进行…