文章目录摘要SQL 数据库关系型数据库NoSQL 数据库什么是反规范化Denormalization5.1 SQL数据库实体关系图ER图5.3 使用SQL还是NoSQLACID的范式5.4 Python数据库框架对象关系映射器ORM。把面向对象的代码自动转换为数据库操作数据库驱动数据类型转换就是把程序里的数据类型转换成数据库能理解的格式或者把数据库返回的数据转换回程序的数据类型性能可移植性数据库管理系统创建、管理和操作数据库的完整软件系统数据库引擎Database Engine数据库系统中负责数据存储和查询执行的核心底层组件数据库管理系统 vs 数据库 vs 数据库引擎Python对象 → ORM → 驱动 → DBMS → 存储引擎 → 磁盘文件在 Flask 项目中如何选择数据库框架Flask-SQLAlchemy 本质上是对 SQLAlchemy 的封装SQLAlchemy 实际连接的是什么5.5 使用Flask-SQLAlchemy管理数据库Flask-SQLAlchemy 的数据库连接 URLDatabase URL格式什么是数据库 URL一种用字符串描述“如何连接数据库”的标准格式通用格式数据库类型://用户名:密码主机名/数据库名mysqlpostgresql,sqlite示例SQLAlchemy 通常还会指定驱动。数据库类型驱动://用户名:密码主机名/数据库名SQLALCHEMY_DATABASE_URI告诉 Flask-SQLAlchemy 要连接哪个数据库SQLALCHEMY_TRACK_MODIFICATIONS配置示例db SQLAlchemy(app)。把 Flask 应用和数据库系统绑定起来并创建一个统一操作数据库的核心对象为什么说“db 表示应用使用的数据库”SQLAlchemy(app) 只是“准备好连接数据库”真正的数据库连接通常发生在第一次实际数据库操作时。SQLite 是个特殊情况。没有网络连接。在第一次访问时打开文件。如果文件不存在会创建文件app.config 是 Flask 应用的“配置字典”。应用的全局设置中心。扩展通过它读取自己的配置db.init_app(app)先创建再绑定app.config.from_object(xx)加载对应配置类里的设置到 app.config字段为什么 Flask 必须有 application context 才能访问数据库Flask-SQLAlchemy 创建的 db 需要和 Flask app 配合使用。Flask-SQLAlchemy 把数据库配置、engine、session 管理都放到了 Flask app 体系里原生 SQLAlchemy 创建的 engine/session 不需要 Flask 的请求上下文也不需要 Flask 的 application contexapplication context 是什么每当有请求进入自动创建应用的上下文5.6 定义模型模型 用 Python 类表示数据库表。模型就是用面向对象方式操作数据库表。在 ORM 里一个类 → 一张表。类的属性 → 表的列。类的实例 → 表中的一行数据db.Model 是什么所有模型类必须继承的基类5.7 关系relationship()是用来在 Python 里建立两个模型之间的联系relationship参数第一个参数是要关联的“目标模型”back_populates 是手动建立“双方都知道对方”的关系。back_populates 写的是对方模型里 relationship 对应的变量名backref —— 自动创建“反向访问”在对方的模型里自动生成一个属性如果你在父表里写了 backref子表就不需要再手动写那个属性ORM 会帮你自动创建primaryjoin —— 指定怎么连接lazy —— 决定访问关系属性时数据库什么时候发 SQLuselist —— 控制是不是列表order_by —— 排序secondary —— 告诉 ORM两张表之间要“通过第三张表连接”secondaryjoin —— 多对多复杂连接primaryjoin / secondaryjoin靠外键建立联系。它根据 ForeignKey 自动推断 JOIN 条件relationship 返回的到底是什么属性描述器返回值具体是什么取决于关系类型怎么知道是一对多还是多对一的关系看外键在哪一边把外键和db.relationship()都放在“多”这一侧连接数据库的工具DBeaver (Community Edition)下载安装5.8 数据库操作5.8.1 创建表 db.create_all()5.8.2 插入行数据库Session会话。也称事务为什么必须要有 session为什么是 db.session当前 Flask 应用绑定的数据库db,是SQLAlchemy对象里面就包含session(数据库会话)db.session 是绑定在 SQLAlchemy 实例上的不同代码块的应用上下文不同的请求对应的db.session不一样db.session “当前请求专属的数据库会话”。只要不在请求里用 db.session 就必须加 app.app_context()。每次浏览器请求进来都会给独立的db.sessiondb.session 依赖 Flask 的“应用上下文app context那什么时候“自动有应用上下文”没有应用上下文需要手动加上下文。只要不在请求里用 db.session 就必须加 app.app_context()为什么“请求里”就可以用 db.session处理请求flask会自动创建应用上下文“请求来了之后Flask 内部到底发生了什么”Flask 有两种上下文请求时自动创建最常见.你可以手动创建app.app_context()为什么要有app.app_context()给flask提供在哪个应用里操作这样session等可以工作还有别的 session 吗引擎是 SQLAlchemy 在数据库驱动之上的一层封装Flask-SQLAlchemy 已经自动创建了 engine 和 db.session如果我想自己手动创建一个新的 session但还是用这个 engine该怎么操作db.engine和db.get_engine()获取引擎的区别如果不是浏览器的请求就不用db.session? 比如有定时任务需要操作数据库用什么session?使用 db.session手动创建 session手动关闭session事务一组必须“要么全部成功要么全部失败”的数据库操作。session是事务的容器事务失败后 必须手动 db.session.rollback()user_john User(usernamejohn, roleadmin_role)在 flask shell 里其实已经自动帮你推入了 app context。所以你才能直接用db.session.add(admin_role)而不报错。add_all参数是一个“可迭代对象”iterable5.8.5 查询行filter_by(...)若想查看SQLAlchemy为查询生成的原生SQL查询语句只需把query对象转换成字符串filter()filter_by()limit(n)offset(n)order_by()group_by()真正“执行查询”并返回结果的方法allfirstfirst_or_404getget_or_404countpaginate5.10 集成Python shell。shell_context_processor 是给 Flask shell 预加载变量用的5.11 使用Flask-Migrate实现数据库迁移5.11.1 创建迁移仓库migrate Migrate(app, db)把 Flask 应用 和 SQLAlchemy 数据库 绑定到 Flask-Migrate。什么是数据库迁移flask db init 初始化 Alembic迁移引擎正常迁移流程5.11.2 创建迁移脚本Alembic 的 版本管理和迁移逻辑flask db migrate -m initial migration5.11.3 更新数据库使用 flask db stamp 标记数据库摘要SQL 数据库关系型数据库NoSQL 数据库什么是反规范化Denormalization5.1 SQL数据库实体关系图ER图5.3 使用SQL还是NoSQLACID的范式5.4 Python数据库框架对象关系映射器ORM。把面向对象的代码自动转换为数据库操作数据库驱动数据类型转换就是把程序里的数据类型转换成数据库能理解的格式或者把数据库返回的数据转换回程序的数据类型性能可移植性数据库管理系统创建、管理和操作数据库的完整软件系统数据库引擎Database Engine数据库系统中负责数据存储和查询执行的核心底层组件数据库引擎Storage Engine是数据库管理系统DBMS里的一个组件它负责实际存储和读取数据。数据库管理系统 vs 数据库 vs 数据库引擎Python对象 → ORM → 驱动 → DBMS → 存储引擎 → 磁盘文件在 Flask 项目中如何选择数据库框架Flask-SQLAlchemy 本质上是对 SQLAlchemy 的封装SQLAlchemy 实际连接的是什么5.5 使用Flask-SQLAlchemy管理数据库Flask-SQLAlchemy 的数据库连接 URLDatabase URL格式什么是数据库 URL一种用字符串描述“如何连接数据库”的标准格式通用格式数据库类型://用户名:密码主机名/数据库名mysqlpostgresql,sqlite示例SQLAlchemy 通常还会指定驱动。数据库类型驱动://用户名:密码主机名/数据库名SQLALCHEMY_DATABASE_URI告诉 Flask-SQLAlchemy 要连接哪个数据库SQLALCHEMY_TRACK_MODIFICATIONS配置示例db SQLAlchemy(app)。把 Flask 应用和数据库系统绑定起来并创建一个统一操作数据库的核心对象db 对象是SQLAlchemy 类的实例表示应用使用的数据库.详情见本章引擎章节为什么说“db 表示应用使用的数据库”SQLAlchemy(app) 只是“准备好连接数据库”真正的数据库连接通常发生在第一次实际数据库操作时。SQLite 是个特殊情况。没有网络连接。在第一次访问时打开文件。如果文件不存在会创建文件app.config 是 Flask 应用的“配置字典”。应用的全局设置中心。扩展通过它读取自己的配置db.init_app(app)先创建再绑定def create_app(config_name): app Flask(__name__) app.config.from_object(config_map[config_name]) db.init_app(app) return appapp.config.from_object(xx)加载对应配置类里的设置到 app.config字段为什么 Flask 必须有 application context 才能访问数据库Flask-SQLAlchemy 创建的 db 需要和 Flask app 配合使用。Flask-SQLAlchemy 把数据库配置、engine、session 管理都放到了 Flask app 体系里Flask-SQLAlchemy 这个扩展需要通过当前 app 读取配置、拿 engine、拿 session、做请求结束后的清理。原生 SQLAlchemy 创建的 engine/session 不需要 Flask 的请求上下文也不需要 Flask 的 application contexFlask-SQLAlchemy 会帮你把 session 和 Flask 请求上下文绑定并自动清理原生 SQLAlchemy 不会自动知道 Flask 请求边界所以要你自己管理。application context 是什么每当有请求进入自动创建应用的上下文5.6 定义模型模型 用 Python 类表示数据库表。模型就是用面向对象方式操作数据库表。在 ORM 里一个类 → 一张表。类的属性 → 表的列。类的实例 → 表中的一行数据db.Model 是什么所有模型类必须继承的基类5.7 关系relationship()是用来在 Python 里建立两个模型之间的联系relationship参数第一个参数是要关联的“目标模型”back_populates 是手动建立“双方都知道对方”的关系。backref也有这个同步的功能back_populates 写的是对方模型里 relationship 对应的变量名backref —— 自动创建“反向访问”在对方的模型里自动生成一个属性如果你在父表里写了 backref子表就不需要再手动写那个属性ORM 会帮你自动创建primaryjoin —— 指定怎么连接lazy —— 决定访问关系属性时数据库什么时候发 SQL值含义小白理解select默认首次访问时查询惰性加载你不访问 users不发 SQL访问时发一次 SQLjoined使用 JOIN 一次查出查询 Role 时顺便 join 查出所有 Usersubquery使用子查询查询 Role 后再发子查询查 users一次加载但分两步immediate主对象加载完就加载一创建 Role就查 usersnoload永远不加载不管访问不访问永远不查用户dynamic不返回列表而返回查询对象不加载 users只返回 query可以继续 filter、order_byuselist —— 控制是不是列表order_by —— 排序secondary —— 告诉 ORM两张表之间要“通过第三张表连接”secondaryjoin —— 多对多复杂连接primaryjoin / secondaryjoinprimaryjoin 是指 第一段连接不一定是怎么和中间表连只有多对多才是怎么和第一张表连一对多就是怎么 和对方连。secondaryjoin 第二段连接只有多对多才有靠外键建立联系。它根据 ForeignKey 自动推断 JOIN 条件relationship 返回的到底是什么属性描述器返回值具体是什么取决于关系类型父对象的 relationship 属性是列表列表里是单个子对象子对象的 relationship 属性是单个父对象怎么知道是一对多还是多对一的关系看外键在哪一边把外键和db.relationship()都放在“多”这一侧连接数据库的工具DBeaver (Community Edition)下载安装官网下载地址5.8 数据库操作5.8.1 创建表 db.create_all()db.create_all()不会重新创建或者更新相应的表5.8.2 插入行数据库Session会话。也称事务为什么必须要有 session为什么是 db.session当前 Flask 应用绑定的数据库db,是SQLAlchemy对象里面就包含session(数据库会话)db.session 是绑定在 SQLAlchemy 实例上的不同代码块的应用上下文不同的请求对应的db.session不一样重复调用1个请求和一个应用上下文db.session每次都是新的db.session “当前请求专属的数据库会话”。只要不在请求里用 db.session 就必须加 app.app_context()。每次浏览器请求进来都会给独立的db.session一个请求 一个 session浏览器请求 → Flask → db.session → 数据库 请求结束 session 自动清理db.session 依赖 Flask 的“应用上下文app context那什么时候“自动有应用上下文”没有应用上下文需要手动加上下文。只要不在请求里用 db.session 就必须加 app.app_context()为什么“请求里”就可以用 db.session处理请求flask会自动创建应用上下文“请求来了之后Flask 内部到底发生了什么”Flask 有两种上下文请求时自动创建最常见.你可以手动创建app.app_context()为什么要有app.app_context()给flask提供在哪个应用里操作这样session等可以工作还有别的 session 吗引擎是 SQLAlchemy 在数据库驱动之上的一层封装Flask-SQLAlchemy 已经自动创建了 engine 和 db.session如果我想自己手动创建一个新的 session但还是用这个 engine该怎么操作db.engine和db.get_engine()获取引擎的区别如果不是浏览器的请求就不用db.session? 比如有定时任务需要操作数据库用什么session?Web 请求Flask 自动创建 context → 提供 db.session → 自动销毁⚙️ 定时 任务你自己创建 context → 使用 db.session → 手动控制使用 db.session手动创建 sessionfrom flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import sessionmaker app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///data.sqlite db SQLAlchemy(app) with app.app_context(): engine db.get_engine() Session sessionmaker(bindengine) def celery_task(): session Session() try: user User(nameAlice) session.add(user) session.commit() except Exception: session.rollback() raise finally: session.close()手动关闭session事务一组必须“要么全部成功要么全部失败”的数据库操作。session是事务的容器事务失败后 必须手动 db.session.rollback()user_john User(username‘john’, roleadmin_role)在 flask shell 里其实已经自动帮你推入了 app context。所以你才能直接用db.session.add(admin_role)而不报错。add_all参数是一个“可迭代对象”iterable5.8.5 查询行filter_by(…)若想查看SQLAlchemy为查询生成的原生SQL查询语句只需把query对象转换成字符串filter()filter_by()limit(n)offset(n)order_by()group_by()真正“执行查询”并返回结果的方法allfirstfirst_or_404getget_or_404countpaginate5.10 集成Python shell。shell_context_processor 是给 Flask shell 预加载变量用的5.11 使用Flask-Migrate实现数据库迁移5.11.1 创建迁移仓库migrate Migrate(app, db)把 Flask 应用 和 SQLAlchemy 数据库 绑定到 Flask-Migrate。什么是数据库迁移flask db init 初始化 Alembic迁移引擎正常迁移流程5.11.2 创建迁移脚本Alembic 的 版本管理和迁移逻辑flask db migrate -m “initial migration”5.11.3 更新数据库使用 flask db stamp 标记数据库
第5章数据库,实体关系图,ER图
文章目录摘要SQL 数据库关系型数据库NoSQL 数据库什么是反规范化Denormalization5.1 SQL数据库实体关系图ER图5.3 使用SQL还是NoSQLACID的范式5.4 Python数据库框架对象关系映射器ORM。把面向对象的代码自动转换为数据库操作数据库驱动数据类型转换就是把程序里的数据类型转换成数据库能理解的格式或者把数据库返回的数据转换回程序的数据类型性能可移植性数据库管理系统创建、管理和操作数据库的完整软件系统数据库引擎Database Engine数据库系统中负责数据存储和查询执行的核心底层组件数据库管理系统 vs 数据库 vs 数据库引擎Python对象 → ORM → 驱动 → DBMS → 存储引擎 → 磁盘文件在 Flask 项目中如何选择数据库框架Flask-SQLAlchemy 本质上是对 SQLAlchemy 的封装SQLAlchemy 实际连接的是什么5.5 使用Flask-SQLAlchemy管理数据库Flask-SQLAlchemy 的数据库连接 URLDatabase URL格式什么是数据库 URL一种用字符串描述“如何连接数据库”的标准格式通用格式数据库类型://用户名:密码主机名/数据库名mysqlpostgresql,sqlite示例SQLAlchemy 通常还会指定驱动。数据库类型驱动://用户名:密码主机名/数据库名SQLALCHEMY_DATABASE_URI告诉 Flask-SQLAlchemy 要连接哪个数据库SQLALCHEMY_TRACK_MODIFICATIONS配置示例db SQLAlchemy(app)。把 Flask 应用和数据库系统绑定起来并创建一个统一操作数据库的核心对象为什么说“db 表示应用使用的数据库”SQLAlchemy(app) 只是“准备好连接数据库”真正的数据库连接通常发生在第一次实际数据库操作时。SQLite 是个特殊情况。没有网络连接。在第一次访问时打开文件。如果文件不存在会创建文件app.config 是 Flask 应用的“配置字典”。应用的全局设置中心。扩展通过它读取自己的配置db.init_app(app)先创建再绑定app.config.from_object(xx)加载对应配置类里的设置到 app.config字段为什么 Flask 必须有 application context 才能访问数据库Flask-SQLAlchemy 创建的 db 需要和 Flask app 配合使用。Flask-SQLAlchemy 把数据库配置、engine、session 管理都放到了 Flask app 体系里原生 SQLAlchemy 创建的 engine/session 不需要 Flask 的请求上下文也不需要 Flask 的 application contexapplication context 是什么每当有请求进入自动创建应用的上下文5.6 定义模型模型 用 Python 类表示数据库表。模型就是用面向对象方式操作数据库表。在 ORM 里一个类 → 一张表。类的属性 → 表的列。类的实例 → 表中的一行数据db.Model 是什么所有模型类必须继承的基类5.7 关系relationship()是用来在 Python 里建立两个模型之间的联系relationship参数第一个参数是要关联的“目标模型”back_populates 是手动建立“双方都知道对方”的关系。back_populates 写的是对方模型里 relationship 对应的变量名backref —— 自动创建“反向访问”在对方的模型里自动生成一个属性如果你在父表里写了 backref子表就不需要再手动写那个属性ORM 会帮你自动创建primaryjoin —— 指定怎么连接lazy —— 决定访问关系属性时数据库什么时候发 SQLuselist —— 控制是不是列表order_by —— 排序secondary —— 告诉 ORM两张表之间要“通过第三张表连接”secondaryjoin —— 多对多复杂连接primaryjoin / secondaryjoin靠外键建立联系。它根据 ForeignKey 自动推断 JOIN 条件relationship 返回的到底是什么属性描述器返回值具体是什么取决于关系类型怎么知道是一对多还是多对一的关系看外键在哪一边把外键和db.relationship()都放在“多”这一侧连接数据库的工具DBeaver (Community Edition)下载安装5.8 数据库操作5.8.1 创建表 db.create_all()5.8.2 插入行数据库Session会话。也称事务为什么必须要有 session为什么是 db.session当前 Flask 应用绑定的数据库db,是SQLAlchemy对象里面就包含session(数据库会话)db.session 是绑定在 SQLAlchemy 实例上的不同代码块的应用上下文不同的请求对应的db.session不一样db.session “当前请求专属的数据库会话”。只要不在请求里用 db.session 就必须加 app.app_context()。每次浏览器请求进来都会给独立的db.sessiondb.session 依赖 Flask 的“应用上下文app context那什么时候“自动有应用上下文”没有应用上下文需要手动加上下文。只要不在请求里用 db.session 就必须加 app.app_context()为什么“请求里”就可以用 db.session处理请求flask会自动创建应用上下文“请求来了之后Flask 内部到底发生了什么”Flask 有两种上下文请求时自动创建最常见.你可以手动创建app.app_context()为什么要有app.app_context()给flask提供在哪个应用里操作这样session等可以工作还有别的 session 吗引擎是 SQLAlchemy 在数据库驱动之上的一层封装Flask-SQLAlchemy 已经自动创建了 engine 和 db.session如果我想自己手动创建一个新的 session但还是用这个 engine该怎么操作db.engine和db.get_engine()获取引擎的区别如果不是浏览器的请求就不用db.session? 比如有定时任务需要操作数据库用什么session?使用 db.session手动创建 session手动关闭session事务一组必须“要么全部成功要么全部失败”的数据库操作。session是事务的容器事务失败后 必须手动 db.session.rollback()user_john User(usernamejohn, roleadmin_role)在 flask shell 里其实已经自动帮你推入了 app context。所以你才能直接用db.session.add(admin_role)而不报错。add_all参数是一个“可迭代对象”iterable5.8.5 查询行filter_by(...)若想查看SQLAlchemy为查询生成的原生SQL查询语句只需把query对象转换成字符串filter()filter_by()limit(n)offset(n)order_by()group_by()真正“执行查询”并返回结果的方法allfirstfirst_or_404getget_or_404countpaginate5.10 集成Python shell。shell_context_processor 是给 Flask shell 预加载变量用的5.11 使用Flask-Migrate实现数据库迁移5.11.1 创建迁移仓库migrate Migrate(app, db)把 Flask 应用 和 SQLAlchemy 数据库 绑定到 Flask-Migrate。什么是数据库迁移flask db init 初始化 Alembic迁移引擎正常迁移流程5.11.2 创建迁移脚本Alembic 的 版本管理和迁移逻辑flask db migrate -m initial migration5.11.3 更新数据库使用 flask db stamp 标记数据库摘要SQL 数据库关系型数据库NoSQL 数据库什么是反规范化Denormalization5.1 SQL数据库实体关系图ER图5.3 使用SQL还是NoSQLACID的范式5.4 Python数据库框架对象关系映射器ORM。把面向对象的代码自动转换为数据库操作数据库驱动数据类型转换就是把程序里的数据类型转换成数据库能理解的格式或者把数据库返回的数据转换回程序的数据类型性能可移植性数据库管理系统创建、管理和操作数据库的完整软件系统数据库引擎Database Engine数据库系统中负责数据存储和查询执行的核心底层组件数据库引擎Storage Engine是数据库管理系统DBMS里的一个组件它负责实际存储和读取数据。数据库管理系统 vs 数据库 vs 数据库引擎Python对象 → ORM → 驱动 → DBMS → 存储引擎 → 磁盘文件在 Flask 项目中如何选择数据库框架Flask-SQLAlchemy 本质上是对 SQLAlchemy 的封装SQLAlchemy 实际连接的是什么5.5 使用Flask-SQLAlchemy管理数据库Flask-SQLAlchemy 的数据库连接 URLDatabase URL格式什么是数据库 URL一种用字符串描述“如何连接数据库”的标准格式通用格式数据库类型://用户名:密码主机名/数据库名mysqlpostgresql,sqlite示例SQLAlchemy 通常还会指定驱动。数据库类型驱动://用户名:密码主机名/数据库名SQLALCHEMY_DATABASE_URI告诉 Flask-SQLAlchemy 要连接哪个数据库SQLALCHEMY_TRACK_MODIFICATIONS配置示例db SQLAlchemy(app)。把 Flask 应用和数据库系统绑定起来并创建一个统一操作数据库的核心对象db 对象是SQLAlchemy 类的实例表示应用使用的数据库.详情见本章引擎章节为什么说“db 表示应用使用的数据库”SQLAlchemy(app) 只是“准备好连接数据库”真正的数据库连接通常发生在第一次实际数据库操作时。SQLite 是个特殊情况。没有网络连接。在第一次访问时打开文件。如果文件不存在会创建文件app.config 是 Flask 应用的“配置字典”。应用的全局设置中心。扩展通过它读取自己的配置db.init_app(app)先创建再绑定def create_app(config_name): app Flask(__name__) app.config.from_object(config_map[config_name]) db.init_app(app) return appapp.config.from_object(xx)加载对应配置类里的设置到 app.config字段为什么 Flask 必须有 application context 才能访问数据库Flask-SQLAlchemy 创建的 db 需要和 Flask app 配合使用。Flask-SQLAlchemy 把数据库配置、engine、session 管理都放到了 Flask app 体系里Flask-SQLAlchemy 这个扩展需要通过当前 app 读取配置、拿 engine、拿 session、做请求结束后的清理。原生 SQLAlchemy 创建的 engine/session 不需要 Flask 的请求上下文也不需要 Flask 的 application contexFlask-SQLAlchemy 会帮你把 session 和 Flask 请求上下文绑定并自动清理原生 SQLAlchemy 不会自动知道 Flask 请求边界所以要你自己管理。application context 是什么每当有请求进入自动创建应用的上下文5.6 定义模型模型 用 Python 类表示数据库表。模型就是用面向对象方式操作数据库表。在 ORM 里一个类 → 一张表。类的属性 → 表的列。类的实例 → 表中的一行数据db.Model 是什么所有模型类必须继承的基类5.7 关系relationship()是用来在 Python 里建立两个模型之间的联系relationship参数第一个参数是要关联的“目标模型”back_populates 是手动建立“双方都知道对方”的关系。backref也有这个同步的功能back_populates 写的是对方模型里 relationship 对应的变量名backref —— 自动创建“反向访问”在对方的模型里自动生成一个属性如果你在父表里写了 backref子表就不需要再手动写那个属性ORM 会帮你自动创建primaryjoin —— 指定怎么连接lazy —— 决定访问关系属性时数据库什么时候发 SQL值含义小白理解select默认首次访问时查询惰性加载你不访问 users不发 SQL访问时发一次 SQLjoined使用 JOIN 一次查出查询 Role 时顺便 join 查出所有 Usersubquery使用子查询查询 Role 后再发子查询查 users一次加载但分两步immediate主对象加载完就加载一创建 Role就查 usersnoload永远不加载不管访问不访问永远不查用户dynamic不返回列表而返回查询对象不加载 users只返回 query可以继续 filter、order_byuselist —— 控制是不是列表order_by —— 排序secondary —— 告诉 ORM两张表之间要“通过第三张表连接”secondaryjoin —— 多对多复杂连接primaryjoin / secondaryjoinprimaryjoin 是指 第一段连接不一定是怎么和中间表连只有多对多才是怎么和第一张表连一对多就是怎么 和对方连。secondaryjoin 第二段连接只有多对多才有靠外键建立联系。它根据 ForeignKey 自动推断 JOIN 条件relationship 返回的到底是什么属性描述器返回值具体是什么取决于关系类型父对象的 relationship 属性是列表列表里是单个子对象子对象的 relationship 属性是单个父对象怎么知道是一对多还是多对一的关系看外键在哪一边把外键和db.relationship()都放在“多”这一侧连接数据库的工具DBeaver (Community Edition)下载安装官网下载地址5.8 数据库操作5.8.1 创建表 db.create_all()db.create_all()不会重新创建或者更新相应的表5.8.2 插入行数据库Session会话。也称事务为什么必须要有 session为什么是 db.session当前 Flask 应用绑定的数据库db,是SQLAlchemy对象里面就包含session(数据库会话)db.session 是绑定在 SQLAlchemy 实例上的不同代码块的应用上下文不同的请求对应的db.session不一样重复调用1个请求和一个应用上下文db.session每次都是新的db.session “当前请求专属的数据库会话”。只要不在请求里用 db.session 就必须加 app.app_context()。每次浏览器请求进来都会给独立的db.session一个请求 一个 session浏览器请求 → Flask → db.session → 数据库 请求结束 session 自动清理db.session 依赖 Flask 的“应用上下文app context那什么时候“自动有应用上下文”没有应用上下文需要手动加上下文。只要不在请求里用 db.session 就必须加 app.app_context()为什么“请求里”就可以用 db.session处理请求flask会自动创建应用上下文“请求来了之后Flask 内部到底发生了什么”Flask 有两种上下文请求时自动创建最常见.你可以手动创建app.app_context()为什么要有app.app_context()给flask提供在哪个应用里操作这样session等可以工作还有别的 session 吗引擎是 SQLAlchemy 在数据库驱动之上的一层封装Flask-SQLAlchemy 已经自动创建了 engine 和 db.session如果我想自己手动创建一个新的 session但还是用这个 engine该怎么操作db.engine和db.get_engine()获取引擎的区别如果不是浏览器的请求就不用db.session? 比如有定时任务需要操作数据库用什么session?Web 请求Flask 自动创建 context → 提供 db.session → 自动销毁⚙️ 定时 任务你自己创建 context → 使用 db.session → 手动控制使用 db.session手动创建 sessionfrom flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import sessionmaker app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] sqlite:///data.sqlite db SQLAlchemy(app) with app.app_context(): engine db.get_engine() Session sessionmaker(bindengine) def celery_task(): session Session() try: user User(nameAlice) session.add(user) session.commit() except Exception: session.rollback() raise finally: session.close()手动关闭session事务一组必须“要么全部成功要么全部失败”的数据库操作。session是事务的容器事务失败后 必须手动 db.session.rollback()user_john User(username‘john’, roleadmin_role)在 flask shell 里其实已经自动帮你推入了 app context。所以你才能直接用db.session.add(admin_role)而不报错。add_all参数是一个“可迭代对象”iterable5.8.5 查询行filter_by(…)若想查看SQLAlchemy为查询生成的原生SQL查询语句只需把query对象转换成字符串filter()filter_by()limit(n)offset(n)order_by()group_by()真正“执行查询”并返回结果的方法allfirstfirst_or_404getget_or_404countpaginate5.10 集成Python shell。shell_context_processor 是给 Flask shell 预加载变量用的5.11 使用Flask-Migrate实现数据库迁移5.11.1 创建迁移仓库migrate Migrate(app, db)把 Flask 应用 和 SQLAlchemy 数据库 绑定到 Flask-Migrate。什么是数据库迁移flask db init 初始化 Alembic迁移引擎正常迁移流程5.11.2 创建迁移脚本Alembic 的 版本管理和迁移逻辑flask db migrate -m “initial migration”5.11.3 更新数据库使用 flask db stamp 标记数据库