- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本篇介绍使用Fastapi + sqlalchemy + alembic 来完成后端服务的数据库管理,并且通过docker-compose来部署后端服务和数据库Mysql。包括:
version: '3'
services:
db:
image: mysql
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码
- MYSQL_DATABASE=tileView
- MYSQL_USER=tile_viewer
- MYSQL_PASSWORD=tv_2024
- TZ=Asia/Shanghai
volumes:
- ./mysql:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
ports:
- 3306:3306
restart: always
部署数据库有三个注意点:
数据库中存储的数据都容器里在/var/lib/mysql目录下,将该目录映射出来,避免重启容器丢失数据 。
2、自动创建数据库DB 。
很多情况下需要在启动数据库容器是自动创建数据库,在environment中设置 MYSQL_DATABASE=tileView即可在容器启动是创建数据库 。
3、创建可读写可远程用户 。
默认情况下非root用户不支持远程连接读写权限,在environment中设置 。
将会获得一个可远程可读写MYSQL_DATABASE库的用户 。
非docker部署情况下使用IP和端口连接数据库,使用docker-compose部署时服务都是自动化启动,事先不知道数据库的IP,这是就可以使用docker-compose提供的能力:使用服务名来请求服务.
docker-compose中可以使用服务的名称来通信,在通信请求中将服务名替换成容器IP.
首先将数据库连接的URL映射到服务的容器中 。
version: '3'
services:
db:
image: mysql
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码
- MYSQL_DATABASE=tileView
- MYSQL_USER=tile_viewer
- MYSQL_PASSWORD=tv_2024
- TZ=Asia/Shanghai
volumes:
- ./mysql:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
interval: 10s
timeout: 5s
retries: 3
server:
image: tileview:1.0
restart: always
container_name: tileview_server
ports:
- "9100:9100"
volumes:
- ./tiles_store:/app/server/tiles_store
- ./log:/app/server/log
- ./upload:/app/server/upload
depends_on:
db:
condition: service_healthy
environment:
- 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:
- db
environment:
- DATABASE_URI=mysql+pymysql://tile_viewer:tv_2024@db/tileView
sqlalchemy 连接数据库时,数据库的url配置从环境变量中获取 。
sqlalchemy/database.py 。
import os
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_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.ini中,如果要使用环境变量中动态获取的方法,需要改变两点:
alembic.ini中不配置数据库连接信息 。
在alembic/env.py动态获取连接url,并设置到alembic.ini中 。
alembic/env.py 。
from logging.config import fileConfig
from 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 # noqa
from server.db.base import Base # noqa
basedir = os.path.split(os.getcwd())[0]
sys.path.append(basedir)
target_metadata = Base.metadata
def 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 URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script 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 Engine
and 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: mysql
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=tv_2024 # root用户密码
- MYSQL_DATABASE=tileView
- MYSQL_USER=tile_viewer
- MYSQL_PASSWORD=tv_2024
- TZ=Asia/Shanghai
volumes:
- ./mysql:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
ports:
- 3306:3306
restart: always
healthcheck:
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
interval: 10s
timeout: 5s
retries: 3
当健康检查完成才代表数据库启动成功,服务才会启动。服务中也需要依赖数据库健康检查完成,写法如下:
depends_on:
db:
condition: service_healthy
最后此篇关于docker-compose部署下Fastapi中使用sqlalchemy和Alembic的文章就讲到这里了,如果你想了解更多关于docker-compose部署下Fastapi中使用sqlalchemy和Alembic的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试将我的 Flask 项目与 Alembic 我的应用程序结构看起来像 project/ configuration/ __init__.
我将 Alembic 与 SQLAlchemy 结合使用来执行模式迁移 和 data migration . 由于我在项目的主应用程序 myapp 中将特定于迁移的依赖项存储在它们自己的模块中(根据
这是已经发生和正在发生的事件链 第 0 天:我开发并部署了我的应用程序 第 1 天:我创建了新数据库 第 3 天:我意识到我想在现有表中添加一个新行。我找到了flask-migrate,我想用它来迁移
我正在尝试在 Alembic 上创建一个新的迁移,它将新枚举类型的新列添加到现有表中。但是我收到一个我认为 Alembic 会自动处理的错误。 我使用的是 Postgres 9.6.6、Alembic
我将 Alembic 与 SQLAlchemy 一起使用。使用 SQLAlchemy,我倾向于遵循不将连接字符串与版本化代码一起存储的模式。相反,我有包含任何 secret 信息的文件 secret.
背景 我正在尝试在此 Flask + RESTplus server example 中使用 PostgreSQL 后端而不是 Sqlite . 我遇到了 PasswordType 数据库列类型的问题
我在一个使用 alembic 管理数据库迁移的团队中工作。我最近拉了master,并尝试运行alembic upgrade heads .我收到以下消息; INFO [alembic.runtime
我想为 Flask 应用程序进行迁移。我正在使用 Alembic。 但是,我收到以下错误。 Target database is not up to date. 在线,我读到这与此有关。 http:/
我正在从事一个使用 SQLite 作为数据库并使用 Alembic 作为数据库迁移工具的项目。它包含空间数据,因此空间扩展和 geoalchemy2 包含在项目中。我正在使用 autogenerate
这个问题在这里已经有了答案: change column datatype from array to integer (2 个答案) 关闭 3 年前。 我有一个这样的模型: class Sched
当我想使用 alembic 进行自动生成迁移时出现错误。 项目树: - alembic.ini - axis.py - tree.txt - alembic - en
我正在使用 Alembic 来管理数据库的迁移。多个 Python 包使用同一个数据库,每个包都有自己的迁移路径。 在生成自动迁移时,如何告诉 Alembic 忽略其他包中的表?例如,当我运行时:
我有一个看起来像这样的表 > select * from mytable id value 0 1 hello world 1 2 hello_world 2 3 hel
我正在使用 alembic 根据用户定义的 sqlalchemy 模型管理数据库迁移。我的挑战是 我希望 alembic 忽略对特定表集的任何创建、删除或更改。 注:我的 Q 与这个问题类似 Igno
我有一个 SQLAlchemy 模型,例如 - class UserFavPlace(db.Model): # This model stores the feedback from the
我需要通过向现有表添加一张表和一列来更新我的数据库。 新列和表应该是一对多的关系。 这是 Alembic 修订文件: def upgrade(): op.create_table('categ
我有一个表 'test' 有一个没有约束的列 'Name'。我需要ALTER给它一个 UNIQUE约束。我该怎么做? 我应该使用 op.alter_column('???')或 create_uniq
我有下表 mysql> describe table; +----------------+-------------+------+-----+-------------------+-------
我最初将我的一个 SQLAlchemy 模型定义为: class StreetSegment(db.Model): id = db.Column(db.Integer, autoincreme
我正在使用 Flask-Migrate==2.0.0。它没有正确检测到变化。每次我运行 python manage db migrate 它都会为所有模型生成一个脚本,尽管它们已在以前的修订版中成功添
我是一名优秀的程序员,十分优秀!