docker-compose部署下Fastapi中使用sqlalchemy和Alembic
本篇介绍使用Fastapi + sqlalchemy + alembic 来完成后端服务的数据库管理,并且通过docker-compose来部署后端服务和数据库Mysql。包括:
- 数据库创建,数据库用户创建
- 数据库服务发现
- Fastapi 连接数据库
- Alembic 连接数据库
- 服务健康检查
部署数据库
version: '3'
services:db:image: mysqlcontainer_name: dbenvironment:- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码- MYSQL_DATABASE=tileView- MYSQL_USER=tile_viewer- MYSQL_PASSWORD=tv_2024- TZ=Asia/Shanghaivolumes:- ./mysql:/var/lib/mysql- /etc/localtime:/etc/localtime:roports:- 3306:3306restart: always
部署数据库有三个注意点:
- 将数据库文件映射出来,避免丢失数据
数据库中存储的数据都容器里在/var/lib/mysql目录下,将该目录映射出来,避免重启容器丢失数据
二、自动创建数据库DB
很多情况下需要在启动数据库容器是自动创建数据库,在environment中设置 MYSQL_DATABASE=tileView
即可在容器启动是创建数据库
三、创建可读写可远程用户
默认情况下非root用户不支持远程连接读写权限,在environment中设置
- MYSQL_USER=tile_viewer
- MYSQL_PASSWORD=tv_2024
将会获得一个可远程可读写MYSQL_DATABASE库的用户
Fastapi 连接数据库
非docker部署情况下使用IP和端口连接数据库,使用docker-compose部署时服务都是自动化启动,事先不知道数据库的IP,这是就可以使用docker-compose提供的能力:使用服务名来请求服务。
docker-compose中可以使用服务的名称来通信,在通信请求中将服务名替换成容器IP。
首先将数据库连接的URL映射到服务的容器中
version: '3'
services:db:image: mysqlcontainer_name: dbenvironment:- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码- MYSQL_DATABASE=tileView- MYSQL_USER=tile_viewer- MYSQL_PASSWORD=tv_2024- TZ=Asia/Shanghaivolumes:- ./mysql:/var/lib/mysql- /etc/localtime:/etc/localtime:roports:- 3306:3306restart: alwayshealthcheck:test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]interval: 10stimeout: 5sretries: 3server:image: tileview:1.0restart: alwayscontainer_name: tileview_serverports:- "9100:9100"volumes:- ./tiles_store:/app/server/tiles_store- ./log:/app/server/log- ./upload:/app/server/uploaddepends_on:db:condition: service_healthyenvironment:- DATABASE_URI=mysql+pymysql://tile_viewer:tv_2024@db/tileView
depends_on: 表示该服务依赖db服务,db服务要先启动。condition: service_healthy
DATABASE_URI:表示将数据库连接信息注入到该容器中,其中@db表示数据库IP:端口号 使用数据库服务名称db来替换,在容器中请求该url时,docker-compose会自动将db转换成对应的数据库的IP和端口号。
depends_on:- dbenvironment:- DATABASE_URI=mysql+pymysql://tile_viewer:tv_2024@db/tileView
修改sqlalchemy中数据库的连接
sqlalchemy 连接数据库时,数据库的url配置从环境变量中获取
sqlalchemy/database.py
import osfrom sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmakerSQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URI")
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)Base = declarative_base()
使用环境变量获取数据库
SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URI")
在Fastapi 服务 调用数据库的方法。
DATABASE_URI=mysql+pymysql://tile_viewer:tv_2024@db/tileView
使用数据库服务名db来找到服务地址,在docker-compose中会将服务名解析成服务的IP。在使用时会将db解析成172.10.0.2,找到服务的IP。
迁移工具alembic中数据库连接
在数据库迁移工具中需要配置数据库的连接信息,该信息是配置在alembic.ini中,如果要使用环境变量中动态获取的方法,需要改变两点:
- alembic.ini中不配置数据库连接信息
- 在alembic/env.py动态获取连接url,并设置到alembic.ini中
alembic.ini中不配置数据库连接信息
在alembic/env.py动态获取连接url,并设置到alembic.ini中
alembic/env.py
from logging.config import fileConfigfrom alembic import context
from sqlalchemy import engine_from_config, pool# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:fileConfig(config.config_file_name)# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.import os # noqa
import sys # noqafrom server.db.base import Base # noqabasedir = os.path.split(os.getcwd())[0]
sys.path.append(basedir)target_metadata = Base.metadatadef get_url() -> str:return os.getenv("DATABASE_URI", "sqlite:///app.db")def run_migrations_offline() -> None:"""Run migrations in 'offline' mode.This configures the context with just a URLand not an Engine, though an Engine is acceptablehere as well. By skipping the Engine creationwe don't even need a DBAPI to be available.Calls to context.execute() here emit the given string to thescript output."""# url = config.get_main_option("sqlalchemy.url")url = get_url()context.configure(url=url,target_metadata=target_metadata,literal_binds=True,dialect_opts={"paramstyle": "named"},)with context.begin_transaction():context.run_migrations()def run_migrations_online() -> None:"""Run migrations in 'online' mode.In this scenario we need to create an Engineand associate a connection with the context."""configuration = config.get_section(config.config_ini_section)configuration["sqlalchemy.url"] = get_url()connectable = engine_from_config(configuration,prefix="sqlalchemy.",poolclass=pool.NullPool,)with connectable.connect() as connection:context.configure(connection=connection, target_metadata=target_metadata)with context.begin_transaction():context.run_migrations()if context.is_offline_mode():run_migrations_offline()
else:run_migrations_online()
在 run_migrations_offline 中将url获取从配置文件中改成从环境变量中
# url = config.get_main_option("sqlalchemy.url")
url = get_url()
在 run_migrations_online 中修改配置文件的数据库连接信息
configuration = config.get_section(config.config_ini_section)
configuration["sqlalchemy.url"] = get_url()
connectable = engine_from_config(configuration,prefix="sqlalchemy.",poolclass=pool.NullPool,
)
以上操作之后就能通过服务发现的方式动态使用数据库
数据库健康检查
在前面的配置中虽然让服务依赖db,db会先启动然后服务后启动,但是这种情况还会出现数据库连不上的情况,因为db启动不代表服务就绪,未就绪的时候连接会导致connect refuse。解决这个问题的方法是给db增加一个健康检查 healthcheck。
services:db:image: mysqlcontainer_name: dbenvironment:- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码- MYSQL_DATABASE=tileView- MYSQL_USER=tile_viewer- MYSQL_PASSWORD=tv_2024- TZ=Asia/Shanghaivolumes:- ./mysql:/var/lib/mysql- /etc/localtime:/etc/localtime:roports:- 3306:3306restart: alwayshealthcheck:test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]interval: 10stimeout: 5sretries: 3
当健康检查完成才代表数据库启动成功,服务才会启动。服务中也需要依赖数据库健康检查完成,写法如下:
depends_on:db:condition: service_healthy
相关文章:

docker-compose部署下Fastapi中使用sqlalchemy和Alembic
本篇介绍使用Fastapi sqlalchemy alembic 来完成后端服务的数据库管理,并且通过docker-compose来部署后端服务和数据库Mysql。包括: 数据库创建,数据库用户创建数据库服务发现Fastapi 连接数据库Alembic 连接数据库服务健康检查 部署数据…...
Oracle:ORA-00904: “10“: 标识符无效报错详解
1.报错Oracle语句如下 SELECT YK_CKGY.ID,YK_CKGY.DJH,YK_CKGY.BLRQ,YK_CKGY.ZBRQ,YK_CKGY.SHRQ,YK_CKGY.YT,YK_CKGY.ZDR,YK_CKGY.SHR,YK_CKGY.BZ,YK_CKGY.JZRQ,YK_CKGY.ZT,YK_CKGY.CKLX,(case YK_CKGY.CKLXwhen 09 then药房调借when 02 then科室退药when 03 then损耗出库when…...

C语言#define定义宏
目录 一、什么是宏以及宏的声明方式 1.宏常量: 2.宏函数: 二、宏的替换原则 三、宏设计的易犯错误 ERROR1:尾部加分号(当然有些特定需要加了分号,这里说明一般情况) ERROR2:宏函数定义时&…...

SpringBoot操作spark处理hdfs文件
SpringBoot操作spark处理hdfs文件 1、导入依赖 <!-- spark依赖--><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.2.2</version></dependency><depend…...
消息队列架构、选型、专有名词解释
私人博客传送门 消息队列专有名词解释 | 魔筝炼药师 MQ选型 | 魔筝炼药师 MQ架构 | 魔筝炼药师 MQ顺序消息 | 魔筝炼药师...

用OpenCV实现UVC视频分屏
分屏 OpencvUVC代码验证后话 用OpenCV实现UVC摄像头的视频分屏。 Opencv opencv里有很多视频图像的处理功能。 UVC Usb 视频类,免驱动的。视频流格式有MJPG和YUY2。MJPG是RGB三色通道的。要对三通道进行分屏显示。 代码 import cv2 import numpy as np video …...
Allure 集成 pytest
Allure 是一个强大的测试报告工具,与 pytest 集成可以生成详细的测试报告,包括测试步骤、测试数据、截图、错误堆栈等。 1. 安装 Allure 和相关依赖 安装 pytest-allure-adaptor 插件: pip install allure-pytest确保本地已安装 Allure 工具。…...
【Python】构建智能语音助手:使用Python实现语音识别与合成的全面指南
随着人工智能技术的迅猛发展,语音助手已成为人们日常生活中不可或缺的一部分。从智能手机到智能家居设备,语音交互提供了便捷高效的人机交互方式。本文旨在全面介绍如何利用Python编程语言及其强大的库——SpeechRecognition和gTTS,构建一个基…...
在 Arthas 中调用 Spring Bean 方法
获取 Spring 应用上下文 使用工具类 如果你的项目中有一个工具类实现了 ApplicationContextAware 接口,如 cn.shutdown.pf.utils.SpringContextUtils,可以使用该类获取 ApplicationContext: Component public final class SpringContextUt…...

Nginx入门笔记
Nginx入门笔记 一、Nginx基本概念二、代理1、正向代理2、反向代理 三、准备工作1、CentOS 7安装nginx(1). 安装必要的依赖(2)下载nginx(3)编译安装(4)编译并安装 Nginx(5)启动nginx …...
【单片机】实现一个简单的ADC滤波器
实现一个 ADC的滤波器,PT1 滤波器(也称为一阶低通滤波器),用于对输入信号进行滤波处理。 typedef struct PT1FilterSettings PT1FilterSettings; struct PT1FilterSettings {//! last Filter output valueuint32_t filtValOld;//…...
开源 vGPU 方案 HAMi 解析
开源 vGPU 方案 HAMi 一、k8s 环境下 GPU 资源管理的现状与问题 (一)资源感知与绑定 在 k8s 中,资源与节点紧密绑定。对于 GPU 资源,我们依赖 NVIDIA 提供的 device-plugin 来进行感知,并将其上报到 kube-apiserver…...

备考蓝桥杯:顺序表详解(静态顺序表,vector用法)
目录 1.顺序表的概念 2.静态顺序表的实现 总代码 3.stl库动态顺序表vector 测试代码 1.顺序表的概念 要理解顺序表,我们要先了解一下什么是线性表 线性表是n个具有相同特征的数据元素的序列 这就是一个线性表 a1是表头 a4是表尾 a2是a3的前驱 a3是a2的后继 空…...
OA系统如何做好DDOS防护
OA系统如何做好DDOS防护?在数字化办公蔚然成风的当下,OA(办公自动化)系统作为企业内部管理与协作的神经中枢,其安全性和稳定性直接关系到企业的日常运营效率、信息流通效率以及长远发展。OA系统不仅承载着企业内部的日…...
使用 Python 的 pyttsx3 库进行文本转语音
1. 什么是 pyttsx3? 1.1 pyttsx3 是一个 Python 库,它可以将文本转换为语音。与其他文本转语音库(如 gTTS)不同,pyttsx3 不依赖于网络服务,它使用本地的 TTS(Text-to-Speech)引擎&a…...

如何在Windows上编译OpenCV4.7.0
前言 参考:Win10 下编译 OpenCV 4.7.0详细全过程,包含xfeatures2d 这里在其基础上还出现了一些问题,仅供参考。 正文 一、环境 1、win10 2、cmake-gui 3、opencv4.7.0 4、VS2019 二、编译过程 1、下载需要的文件: 通…...

【玩转全栈】----Django连接MySQL
阅前先赞,养好习惯! 目录 1、ORM框架介绍 选择建议 2、安装mysqlclient 3、创建数据库 4、修改settings,连接数据库 5、对数据库进行操作 创建表 删除表 添加数据 删除数据 修改(更新)数据: 获取数据 1、OR…...
25/1/4 算法笔记<强化学习> 生成对抗模仿学习
基于生成对抗网络的模仿学习,假设存在一个专家智能体,其策略可以看成最优策略,我们就可以通过直接模仿这个专家在环境中交互的动作数据来训练一个策略,并不需要用到环境提供的奖励信息。 生成对抗模仿学习GAIL实质上就是模仿了专家…...
Flink维表方案选型
Iceberg Iceberg 采用全量预加载数据的方式将维度表数据全部加载到内存中进行关联,虽然可以避免频繁访问外部数据库,但对计算节点的内存消耗很高,不能适用于数量很大的维度表。除此之外,当 Iceberg 维表数据更新后,可…...
Oracle Database 23ai 新特性: UPDATE 和 DELETE 语句的直接联接
Oracle Database 23c 引入了一系列令人振奋的新特性,其中一项尤为引人注目的是对 UPDATE 和 DELETE 语句支持直接联接(Direct Join)。这一新功能极大地简化了复杂数据操作的实现,提升了性能,并为数据库开发者提供了更强…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...

qt+vs Generated File下的moc_和ui_文件丢失导致 error LNK2001
qt 5.9.7 vs2013 qt add-in 2.3.2 起因是添加一个新的控件类,直接把源文件拖进VS的项目里,然后VS卡住十秒,然后编译就报一堆 error LNK2001 一看项目的Generated Files下的moc_和ui_文件丢失了一部分,导致编译的时候找不到了。因…...

英国云服务器上安装宝塔面板(BT Panel)
在英国云服务器上安装宝塔面板(BT Panel) 是完全可行的,尤其适合需要远程管理Linux服务器、快速部署网站、数据库、FTP、SSL证书等服务的用户。宝塔面板以其可视化操作界面和强大的功能广受国内用户欢迎,虽然官方主要面向中国大陆…...
【R语言编程——数据调用】
这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...
Angular中Webpack与ngx-build-plus 浅学
Webpack 在 Angular 中的概念 Webpack 是一个模块打包工具,用于将多个模块和资源打包成一个或多个文件。在 Angular 项目中,Webpack 负责将 TypeScript、HTML、CSS 等文件打包成浏览器可以理解的 JavaScript 文件。Angular CLI 默认使用 Webpack 进行项目…...

智能问数Text2SQL Vanna windows场景验证
架构 Vanna 是一个开源 Python RAG(检索增强生成)框架,用于 SQL 生成和相关功能。 机制 Vanna 的工作过程分为两个简单步骤 - 在您的数据上训练 RAG“模型”,然后提出问题,这些问题将返回 SQL 查询,这些查…...