Alembic 是一个用于处理数据库迁移的轻量级工具,通常与 SQLAlchemy 一起使用。它允许你在数据库结构发生变化时,自动化地跟踪和管理这些变化。以下是一个使用 Alembic 进行数据库迁移管理的指南。
环境准备
-
安装 Alembic 和 SQLAlchemy:
pip install alembic sqlalchemy
-
创建项目结构:
假设你有一个项目结构如下:myproject/ ├── alembic/ ├── myapp/ │ ├── __init__.py │ ├── models.py ├── alembic.ini ├── main.py
初始化 Alembic
-
初始化 Alembic:
在项目根目录运行以下命令:alembic init alembic
这将创建一个
alembic
目录,其中包含env.py
、script.py.mako
和versions
目录。 -
配置 Alembic:
编辑alembic.ini
文件,设置 SQLAlchemy 的数据库连接字符串。例如:sqlalchemy.url = sqlite:///mydatabase.db
-
编辑
env.py
:
在alembic/env.py
中,告诉 Alembic 如何获取你的 SQLAlchemy 基础映射类。例如:from logging.config import fileConfig from sqlalchemy import engine_from_config from sqlalchemy import pool from alembic import context # 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. fileConfig(config.config_file_name) # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata from myapp.models import Base target_metadata = Base.metadata # 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. def run_migrations_offline(): """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is also acceptable here. 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") context.configure( url=url, target_metadata=target_metadata, literal_binds=True ) with context.begin_transaction(): context.run_migrations() def run_migrations_online(): """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ connectable = engine_from_config( config.get_section(config.config_ini_section), 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()
创建数据库模型
在 myapp/models.py
中定义你的数据库模型:
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
DATABASE_URL = 'sqlite:///mydatabase.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def init_db():
Base.metadata.create_all(bind=engine)
生成迁移脚本
-
生成迁移脚本:
当你对模型进行更改后,运行以下命令生成迁移脚本:alembic revision --autogenerate -m "create users table"
这将在
alembic/versions
目录下生成一个新的迁移脚本。 -
检查并应用迁移:
生成的迁移脚本可能需要手动检查和修改。完成后,运行以下命令应用迁移:alembic upgrade head
完整示例
以下是一个简单的完整示例:
main.py
:
from myapp.models import init_db
if __name__ == "__main__":
init_db()
myapp/models.py
:
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
DATABASE_URL = 'sqlite:///mydatabase.db'
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def init_db():
Base.metadata.create_all(bind=engine)
总结
通过上述步骤,你可以使用 Alembic 管理你的数据库迁移。Alembic 提供了强大的功能,能够帮助你跟踪和应用数据库架构的变化,从而更好地维护和更新你的数据库。