当前位置: 首页 > news >正文

【SQLAlChemy】表之间的关系,外键如何使用?

表之间的关系

数据库表之间的关系分为三种:

  • 一对一关系(One-to-One):在这种关系中,表A的每一行都与表B的一行关联,反之亦然。例如,每个人都有一个唯一的社保号,每个社保号也只属于一个人。
  • 一对多关系(One-to-Many):在这种关系中,表A的一行可以与表B的多行关联,但表B的每一行只能与表A的一行关联。例如,一位母亲可以有多个孩子,但每个孩子只能有一个生物学上的母亲。
  • 多对多关系(Many-to-Many):在这种关系中,表A的一行可以与表B的多行关联,表B的一行也可以与表A的多行关联。例如,一个学生可以选修多门课程,一门课程也可以被多个学生选修。

在数据库中,这些关系通常通过使用外键(Foreign Key)来建立。

外键

外键(Foreign Key)是一种特殊类型的数据库约束,主要用于创建表之间的链接或关系。

外键是在一个表中创建的,它是另一个表的主键(Primary Key)。这个外键用来指向另一个表的主键,从而建立两个表之间的关系。

外键的主要目的是维护数据的引用完整性。这意味着,如果试图在一个表中插入一行,而这行数据的外键值在相关表中不存在,数据库将不允许这个操作。同样,如果试图删除一个表中的行,而这行数据的主键在其他表中作为外键存在,那么数据库也不会允许这个删除操作,除非先删除或更改引用这个主键的所有外键。

例如,假设有两个表,一个是学生表,一个是课程表。每个学生可以注册多个课程,所以在课程表中,可能会有一个列叫做 "student_id",这个列是学生表的外键。这样,就可以通过学生的 ID 查询他们注册的所有课程,同时也保证了每个课程都有一个注册的学生。

使用 SQLAlchemy 创建外键的步骤:

  1. 定义表格:首先,需要定义数据库表格。每个表格对应一个 SQLAlchemy 类,类中的每个属性对应表格中的一个列。
  2. 设置外键:在定义表格的过程中,可以使用 ForeignKey 函数来设置外键。ForeignKey 函数的参数是想要链接的表格的列名。例如,如果有一个 Order 表,想让它链接到 Customer 表的 id 列,可以这样写: customer_id = Column(Integer, ForeignKey('customer.id'))
  3. 创建关系:在设置了外键之后,还需要在 SQLAlchemy 类中使用 relationship 函数来创建两个表格之间的关系。例如,可以在 Customer 类中添加如下的代码: orders = relationship("Order", backref="customer")。 这段代码表示一个客户可以有多个订单,每个订单都有一个关联的客户。
  4. 创建数据库:最后,需要使用 SQLAlchemy 的 create_all 函数来创建数据库。这个函数会根据定义的 SQLAlchemy 类来创建表格,并设置好所有的外键和关系。

实例

实现学生 StudentLesson 之间的关系表的建立。

python 代码:

Base = declarative_base()# 定义 Student 表
class Student(Base):__tablename__ = 'student'id = Column(Integer, primary_key=True)name = Column(String(50), nullable=False)age = Column(Integer)def __repr__(self):return "<Student(name='%s', age='%s')>" % (self.name, self.age)# 定义 Lesson 表
class Lesson(Base):__tablename__ = 'lesson'id = Column(Integer, primary_key=True)name = Column(String(50), nullable=False)description = Column(String(100), nullable=False)student_id = Column(Integer, ForeignKey('student.id'))def __repr__(self):return "<Lesson(name='%s', description='%s')>" % (self.name, self.description)Base.metadata.create_all(engine)

sql语句代码:

create table student
(id   int auto_incrementprimary key,name varchar(50) not null,age  int         null
);create table lesson
(id          int auto_incrementprimary key,name        varchar(50)  not null,description varchar(100) not null,student_id  int          null,constraint lesson_ibfk_1foreign key (student_id) references student (id)
);create index student_idon lesson (student_id);

表关系图:

测试插入数据:

# 测试插入数据# Student 数据
stu1 = Student(name='zmz', age=10)
stu2 = Student(name='ypb', age=18)
stu3 = Student(name='gll', age=20)session.add_all([stu1, stu2, stu3])
session.commit()# Lesson 数据
l1 = Lesson(name='java', description='this is java', student_id=stu1.id)
l2 = Lesson(name='java', description='this is java', student_id=stu2.id)
l3 = Lesson(name='python', description='this is python', student_id=stu1.id)
session.add_all([l1, l2, l3])
session.commit()

数据库 student 表:

数据库 lesson 表:

外键约束分类

  • RESTRICT:这是默认选项。当尝试删除父表中的数据时,如果子表中存在与之关联的数据,那么这个删除操作将会被阻止。也就是说,只有当没有任何子表行与父表行关联时,才能删除父表中的行。
  • NO ACTION:在 MySQL 中,这个选项的行为与 RESTRICT 选项相同。也就是说,如果子表中存在与父表行关联的行,那么尝试删除父表中的行将会被阻止。
  • CASCADE:这个选项表示级联删除。当你删除父表中的行时,所有在子表中与之关联的行也会被自动删除。这种选项需要谨慎使用,因为它可能会导致大量的数据被删除。
  • SET NULL:当父表中的行被删除时,这个选项会将子表中所有与之关联的行的外键列设置为 NULL。这意味着,子表中的这些行不再与父表中的任何行关联。注意,为了使用这个选项,子表的外键列必须允许 NULL 值。

修改 lesson 表:

# 定义 Lesson 表
class Lesson(Base):__tablename__ = 'lesson'id = Column(Integer, primary_key=True)name = Column(String(50), nullable=False)description = Column(String(100), nullable=False)student_id = Column(Integer, ForeignKey('student.id', ondelete='CASCADE'), nullable=False)def __repr__(self):return "<Lesson(name='%s', description='%s')>" % (self.name, self.description)

注意事项

问题:

加入在添加数据时,我们先提交了 student 中的数据,之后在提交了 lesson 中的数据,会造成 lessonstudent_id 为空。

分析:

在 SQLAlchemy 中,当使用 session.add() 方法时,数据并不会立即被写入数据库,而是被添加到了会话的事务队列中。只有当调用 session.commit() 方法时,才会将这些变更写入数据库。在这之前,新创建的 Student 对象的 id 属性是 None,因为它们还没有被分配数据库中的 id

在代码中,首先创建了几个 Student 对象,并使用 session.add_all() 添加到会话中,但是在添加 Lesson 对象之前,没有调用 session.commit()。因此,当试图访问 stu1.id 时,它其实是 None,这就是为什么在插入 Lesson 数据时会出现错误。
为了解决这个问题,需要在添加 Lesson 对象之前,先提交 Student 对象。

相关文章:

【SQLAlChemy】表之间的关系,外键如何使用?

表之间的关系 数据库表之间的关系分为三种&#xff1a; 一对一关系&#xff08;One-to-One&#xff09;&#xff1a;在这种关系中&#xff0c;表A的每一行都与表B的一行关联&#xff0c;反之亦然。例如&#xff0c;每个人都有一个唯一的社保号&#xff0c;每个社保号也只属于…...

Linux 基础IO 二

1.文件描述符的分配规则 #include<stdio.h> #include<string.h> //#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>int main() {close(1);//fd分配原则&#xff0c;从最小的开始&#xff0c;没有被占用…...

找工作小项目:day15-macOS支持、完善逻辑

macOS支持、完善逻辑 目前的代码可以在Linux上完美运行编译&#xff0c;在Windows上也可以通过WSL编译运行源代码&#xff0c;但是在MacBook上却无法运行编译&#xff0c;这主要是由于macOS上没有epoll&#xff0c;取而代之的很相似的kqueue。由于操作系统不同&#xff0c;我们…...

植物大战僵尸杂交版 v2.0.88 mac版 Plants vs. Zombies 杂交版下载

特别注意&#xff1a;该游戏最低系统要求为macOS Sonoma 14.X&#xff0c;低于此系统版本的请勿下载&#xff01; 游戏介绍 植物大战僵尸杂交版是由B站UP主“潜艇伟伟迷”制作的一款结合了《植物大战僵尸》原有元素与创新玩法的游戏。这款游戏以其独特的“杂交”植物概念在B站…...

PHP中的while循环:用法、技巧与最佳实践

在PHP编程中&#xff0c;while循环是一种基本且常用的控制结构&#xff0c;用于重复执行代码块&#xff0c;直到指定条件为假。while循环在处理未知迭代次数的任务时特别有用&#xff0c;例如读取文件内容、处理用户输入或动态生成数据等。与for循环不同&#xff0c;while循环适…...

如何解决跨境传输常见的安全及效率问题?

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…...

『大模型笔记』主成分分析(PCA)解释:简化机器学习中的复杂数据!

主成分分析(PCA)解释:简化机器学习中的复杂数据 文章目录 一. 主成分分析(PCA)解释:简化机器学习中的复杂数据!二. 参考文献一. 主成分分析(PCA)解释:简化机器学习中的复杂数据! 主成分分析(Principal Component Analysis,简称PCA)通过 将大型数据集中的维度减少…...

springboot与flowable(5):任务分配(表达式)

在做流程定义时我们需要给相关的用户节点指派对应的处理人。在flowable中提供了三种分配的方式。 一、固定分配 在分配用户时选择固定值选项确认即可。 二、表达式 1、值表达式 2、方法表达式 三、表达式流程图测试 1、导出并部署 导出流程图&#xff0c;复制到项目中 部署流…...

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project&#xff0c;选择Import Legacy CCSv3.3 Porjects…&#xff0c;弹出对话框&#xff0c;通过Browse…按钮导入一个3.3版本的工程项目&#xff1b; 选择.pjt文件&#xff0c;选择Copy projects into worlkspace 右击选择P…...

Stable Diffusion 3 Medium 模型

开源SD3&#xff0c;中型版本&#xff0c;20亿参数&#xff0c;Stable Diffusion 3 Medium&#xff0c;系统内存要求32G&#xff0c;显卡6G。 a female character with long, flowing hair that appears to be made of ethereal, swirling patterns resembling the Northern Li…...

数据分析------统计学知识点(五)

回归算法 想象一下&#xff0c;你和朋友在讨论:大学生活中&#xff0c;每天学习的时间是否真的能影响期末成绩?这个问题看似简单&#xff0c;实则包含了一个潜在的关系:学习时间与成绩之间的联系。我们想要知道&#xff0c;增加学习时间是否会提高成绩&#xff0c;以及这种提…...

Superset二次开发之Git篇 git remote

背景:从GitHub clone Superset项目,基于3.0版本做二次开发,后续通过其他方式把3.0版本未做任何修改过的原始代码上传到企业GitLab库develop分支 任务:本地代码推送到GitLab库develop分支,但是两者似乎没有任何关联关系 操作步骤 克隆 Superset 3.0 版本的项目到本地: …...

记录一下PHP使用微信小程序支付

记录一下PHP使用微信小程序支付V3版本经历 官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_0.shtml 请详细查看文档中小程序支付接入前准备&#xff08;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml&#xff…...

【数据结构初阶】 --- 单链表

关于链表你应该先了解这些 下图描述了物理模型和逻辑模型&#xff0c;大多数常见的其实是逻辑模型&#xff0c;但这对初学者或者掌握不扎实的同学不太友好&#xff0c;所以这里我重点讲解物理模型&#xff0c;当了解了这些细节&#xff0c;以后做题或是什么就直接画逻辑模型就…...

并发、多线程、HTTP连接数有何关系?

在计算机领域&#xff0c;"并发"、"多线程"和"HTTP连接数"是三个重要的概念&#xff0c;它们之间存在着密切的关系。本文将探讨这三者之间的联系以及它们在现代计算机系统中的作用。 一、并发的概念 并发是指系统能够同时处理多个任务或事件的能…...

鸿蒙轻内核Kconfig使用笔记

鸿蒙轻内核使用Kconfig进行图形化配置&#xff0c;本文专门讲解下鸿蒙轻内核LiteOS-M和LiteOS-A的图形化配置方法。本文中所涉及的源码&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 、 https://gitee.com/openharmony/kernel_liteos_m 获取。本…...

react 0至1 案例

/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序* 最热 > 喜欢数量降序* 最新 > 创建时间降序* 1.点击记录当前type* 2.通过记录type和当前list中的type 匹配*/ import ./App.scss import avatar from ./images/bozai.png import {useState} …...

基于MCU平台的HMI开发的性能优化与实战(上)

随着汽车座舱智能化的不断演进&#xff0c;车内显示设备的数量显著增加&#xff0c;从传统的仪表盘和中控屏扩展至空调控制、扶手、副驾驶区域以及抬头显示&#xff08;HUD&#xff09;等多样化的显示单元。为了有效支持这些功能单元&#xff0c;同时控制整车成本&#xff0c;越…...

【Tkinter界面】Canvas 图形绘制(02/5)

文章目录 一、说明二、几何时使用 Canvas 组件2.1 用法2.2 简单范例2.3 对象移动2.4 对象删除2.5 文字对象显示 三、画布和画布对象3.1 画布生成函数原型3.2 使用create_xxx()方法3.3 对参数**options的解释 一、说明 Canvas&#xff08;画布&#xff09;组件为 Tkinter 的图形…...

1_常见指令【Linux中常见30个指令的学习和使用】【万字长文】

常见指令以及权限理解 开始学习linux前的注意事项 在学习linux之前&#xff0c;我们要知道linux是一个操作系统。 那操作系统是什么呢&#xff1f;&#xff08;这里只做大概了解&#xff09; 操作系统就是一个管理软硬件的软件。 它对上提供良好&#xff08;稳定、高效、安…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!

今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等&#xff0c;设置经线、纬线都以10间隔显示。 2、需要插入背会归线&#xf…...

云原生安全实战:API网关Envoy的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关 作为微服务架构的统一入口&#xff0c;负责路由转发、安全控制、流量管理等核心功能。 2. Envoy 由Lyft开源的高性能云原生…...

MCP和Function Calling

MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09; &#xff0c;2024年11月底&#xff0c;由 Anthropic 推出的一种开放标准&#xff0c;旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...