Litefs 数据库迁移
更新日期: 2026-10-21 适用版本: v0.9.0(开发中)
概述
Litefs 基于 Alembic 封装数据库版本化迁移能力,提供完整的 init / migrate / upgrade / downgrade / current / history 命令组。
设计原则:
原则 |
实现方式 |
|---|---|
可选依赖 |
|
无状态污染 |
每次命令在独立配置对象中执行,不改写全局配置 |
不劫持日志 |
仅配置 |
向后兼容 |
旧的扁平入口 |
安装
# 仅启用迁移能力
pip install 'litefs[db]'
# 或直接安装依赖
pip install alembic
未安装时执行迁移命令会抛出 AlembicNotAvailable(继承 ImportError),并给出安装指引:
未安装 alembic,请执行 pip install 'litefs[db]' 或 pip install alembic
命令清单
litefs db 命令组
命令 |
说明 |
参数 |
|---|---|---|
|
初始化 Alembic 迁移环境 |
|
|
生成迁移脚本(对比模型与库结构) |
|
|
升级数据库到指定版本 |
|
|
回退数据库到指定版本 |
|
|
显示当前数据库版本 |
— |
|
显示迁移历史 |
— |
|
直接创建全部数据表(不生成迁移脚本) |
— |
旧入口(保持兼容)
命令 |
说明 |
|---|---|
|
建表(旧行为不变) |
|
生成迁移脚本(旧占位提示已升级为真正实现) |
db-init与db create-tables等价;db-migrate与db migrate等价。新代码推荐使用嵌套子命令形式。
快速开始
# 1. 初始化迁移环境(在项目根目录执行)
$ litefs db init
迁移环境初始化完成
配置文件: /path/to/project/alembic.ini
迁移目录: /path/to/project/migrations
下一步: litefs db migrate -m '初始迁移'
# 2. 修改模型后生成迁移脚本
$ litefs db migrate -m "新增用户表"
迁移脚本已生成: 新增用户表
Generating /path/to/project/migrations/versions/92f20e175f75_新增用户表.py ... done
# 3. 应用迁移
$ litefs db upgrade
已升级到版本: head
# 4. 查看当前版本与历史
$ litefs db current
Current revision(s) for sqlite:///litefs.db:
Rev: 92f20e175f75 (head)
Parent: <base>
Path: /path/to/project/migrations/versions/92f20e175f75_新增用户表.py
$ litefs db history
<base> -> 92f20e175f75 (head), 新增用户表
# 5. 需要时回退
$ litefs db downgrade
已回退到版本: -1
生成的目录结构
project/
├── alembic.ini # Alembic 配置(script_location / sqlalchemy.url)
├── app.py
├── models.py # 自定义模型(需被 autogenerate 感知)
└── migrations/
├── env.py # 由 Litefs 生成的自定义环境脚本
├── script.py.mako # 迁移脚本模板
└── versions/ # 迁移脚本存放目录
└── 92f20e175f75_新增用户表.py
自定义 env.py
litefs db init 会用框架自带的模板覆盖 Alembic 默认的 env.py,与默认模板的差异:
target_metadata = Base.metadata—— 指向litefs.database.models.Base,autogenerate依赖它对比模型差异;默认模板的target_metadata = None会导致 autogenerate 直接报错。SQLite 批处理模式 ——
render_as_batch=connection.dialect.name == "sqlite",SQLite 不支持大部分ALTER TABLE,批处理模式可自动改写为"新建表 + 拷贝数据"。不调用
fileConfig()—— 程序化构造的 ini 不含完整 logging 配置段,调用会抛异常;同时也避免劫持宿主应用的 root logger。改为仅配置alembic日志命名空间。显式插入项目根目录到
sys.path—— 保证能导入项目自定义的模型模块。
模板中还预留了自定义模型的导入位置:
# 用户自定义模型模块的导入语句
# import models
litefs db init 会自动探测项目根目录下的 models.py 或 models/ 包并填入该位置。若模型不在根目录,需手工编辑 migrations/env.py 补充导入语句,否则 autogenerate 无法感知这些模型。
数据库连接解析
AlembicManager.database_url 的解析优先级:
构造时显式传入的
database_url环境变量
DATABASE_URLLitefs 配置中的
database_url默认值
sqlite:///litefs.db
CLI 场景下,框架会先从项目的 app.py 中读取 app.db.database_url,读取成功时以最高优先级传入;读取失败则回退到上述顺序。
# 通过环境变量指定数据库
export DATABASE_URL="postgresql://user:pass@127.0.0.1:5432/appdb"
litefs db upgrade
编程接口
from litefs.database import AlembicManager
manager = AlembicManager(
database_url='postgresql://user:pass@127.0.0.1:5432/appdb',
script_location='migrations',
project_root='/path/to/project',
)
code, output = manager.init()
if code != 0:
raise RuntimeError(output)
code, output = manager.migrate('新增用户表')
print(output)
所有公开方法统一返回 (exit_code: int, output: str) 二元组,由调用方决定如何展示输出与退出码。
方法 |
说明 |
|---|---|
|
初始化迁移环境,生成 |
|
生成迁移脚本 |
|
升级到指定版本 |
|
回退到指定版本 |
|
查看当前版本 |
|
查看迁移历史 |
属性
属性 |
说明 |
|---|---|
|
解析后的数据库连接 URL |
|
autogenerate 使用的模型元数据(默认 |
|
迁移目录绝对路径 |
|
|
|
迁移环境是否已初始化( |
异常
异常 |
触发条件 |
|---|---|
|
未安装 |
生产实践
1. 迁移脚本必须进版本库
migrations/versions/ 与 alembic.ini 都应提交到 Git,它们是数据库结构变更的唯一事实来源。
# .gitignore 中不要忽略
# !migrations/
2. 在发布流程中执行升级
# 典型发布脚本
set -e
python -m pip install -e ".[db]"
litefs db upgrade # 失败则中止发布
gunicorn -w 4 -b :8080 wsgi:application
litefs db upgrade 的退出码非 0 时表示迁移失败,可直接用于阻断发布。
3. 先备份再迁移
生产环境的 downgrade 通常不可逆(DROP COLUMN 等操作无法回滚)。执行前请确保有可用的备份或快照。
4. 并发控制
Alembic 自身不带迁移锁。若多个实例同时执行 upgrade,可能出现并发 DDL 冲突。建议:
在发布流程中只由一个实例执行迁移;
或在数据库层加 advisory lock。
5. 大表迁移
SQLite 走批处理模式(render_as_batch=True),大数据量下会走"建新表 → 拷贝数据 → 改名"流程,耗时较长,建议在低峰期执行。
常见问题
Q:执行 litefs db migrate 报 "does not provide a MetaData object"?
A:migrations/env.py 被手工改动过,导致 target_metadata 未赋值。重新执行 litefs db init 重建环境(或将 target_metadata = Base.metadata 补回)。
Q:生成的迁移脚本是空的?
A:说明模型未被 env.py 感知。请确认 migrations/env.py 中已导入自定义模型模块(import models),且模型类继承自 litefs.database.models.Base 或已加入该 Base 的 metadata。
Q:litefs db current 没有输出?
A:数据库中尚未应用任何迁移,执行一次 litefs db upgrade 后再查看。
Q:提示"迁移环境未初始化"?
A:需先在项目根目录执行 litefs db init。
Q:如何在不生成迁移脚本的情况下建表?
A:使用 litefs db create-tables(等价旧的 litefs db-init),直接按模型元数据创建全部数据表。
相关文档
:doc:
configuration—— 配置项完整列表:doc:
prometheus-monitoring—— Prometheus 监控:doc:
static-checks—— 静态检查规范