Alembics是SQLAlchemy的数据库迁移工具。解决SQLAlchemy只能一次性创建数据表,无法更新数据库字段等问题。
起步
安装
pip install alembic
# 初始化
alembic init alembic
配置
[alembic]
sqlalchemy.url = driver://user:pass@localhost/dbname
- 修改配置alembic/env.py
- 搜索"target_metadata"找到代码
- 如下是使用SQLModel
from sqlmodel import SQLModel
from model.user import User
target_metadata = SQLModel.metadata
迁移
- 创建迁移数据
- 通过对比数据库表信息与所有迁移文件,计算出差异字段后再生成新的迁移文件
- 首次使用,如果数据库中已经有表,会影响首次迁移文件
- 建议先连接空数据库,生成迁移文件(记录下alembic_version表的生成SQL,在数据库中插入表)
- 将版本号加到"alembic_version"表中,就不会运行重复执行了
# 创建新记录,并添加表格迁移信息(--autogenerate)
alembic revision -m "add_xxx" --autogenerate
# 在alembic/versions目录下生成一个迁移文件
# 升级
alembic upgrade head
# 创建almebic_version的表(如果不存在)
# 应用迁移文件
# 仅打印sql文件,但暂不修改数据库
alembic upgrade head --sql
# 降级
alembic downgrade <version>
# version在生成迁移文件里,找到down_revision字段
- 手动创建数据表如下
- 最好是连接空数据库,再记录生成的SQL语句(需要引擎echo=True)
# 手动插入alembic数据表(Postgresql)
CREATE TABLE alembic_version (
version_num VARCHAR(32) NOT NULL,
CONSTRAINT alembic_version_pkc PRIMARY KEY (version_num)
);
# 插入版本号
INSERT INTO alembic_version (version_num) VALUES ('2fee77670444');
迁移
生成默认值
- 想在已有数据的表中增加列,新增的列因为性能问题不为空,需要设置个默认值
from sqlmodel import SQLModel, Field, BigInteger, Integer, String
class User(SQLModel, table=True):
__tablename__ = "user"
id: int | None = Field(sa_type=BigInteger, default=None, primary_key=True)
name: str = Field(sa_type=String(32), default="")
age: int = Field(sa_type=Integer, default=0, sa_column_kwargs={"comment": "年龄"})
- 修改生成的代码,"age"字段中,增加"server_default"
* "default"字段在代码端生效,比如插入记录时,赋值默认值
* "server_default"是设置数据库端的默认值,生成"... DEFAULT '0' ..."的SQL语句
* "server_default"只能是str/ClauseElement/TextClause(报错会打印),将字符串设置为SQL语句中单引号内得值即
def upgrade() -> None:
op.add_column(
"user",
sa.Column(
"age",
sa.Integer(),
nullable=False,
comment="年龄",
server_default="0",
),
)
op.execute("ALTER TABLE \"user\" ADD COLUMN age INTEGER DEFAULT '0' NOT NULL")
def downgrade() -> None:
op.drop_column("user", "age")
ALTER TABLE "user" ADD COLUMN age INTEGER DEFAULT '0' NOT NULL
配置
alembic.ini
[alembic]
file_template = %%(year)d%%(month).2d%%(day).2d-%%(slug)s-%%(rev)s
sqlalchemy.url = driver://user:pass@localhost/dbname
alembic/env.py
from sqlmodel import SQLModel
target_metadata = SQLModel.metadata
def run_migrations_offline() -> None:
from setting import get_setting
url = get_setting().db_url
def run_migrations_online() -> None:
from database import engine
connectable = engine
参考文档
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!