Loading...
Loading...
Compare original and translation side by side
down_revisiondown_revisionundefinedundefined
Use `pyproject` template for modern Python projects that already have a `pyproject.toml`. It separates source-code config (in `pyproject.toml`) from deployment config (database URL, logging in `alembic.ini`).
对于已包含`pyproject.toml`的现代Python项目,使用`pyproject`模板。它将源代码配置(在`pyproject.toml`中)与部署配置(数据库URL、`alembic.ini`中的日志配置)分离。yourproject/
├── alembic.ini # DB URL, logging, deployment config
├── pyproject.toml # Source/code config (pyproject template)
└── alembic/
├── env.py # Migration runner — customize here
├── script.py.mako # Template for new revision files
└── versions/
├── 3512b954651e_add_account.py
└── ae1027a6acf_add_column.pyyourproject/
├── alembic.ini # 数据库URL、日志、部署配置
├── pyproject.toml # 源代码配置(pyproject模板)
└── alembic/
├── env.py # 迁移运行器——在此处自定义
├── script.py.mako # 新修订文件的模板
└── versions/
├── 3512b954651e_add_account.py
└── ae1027a6acf_add_column.pyalembic.inialembic.inisqlalchemy.url = postgresql+psycopg2://user:pass@localhost/mydb%import urllib.parse
from sqlalchemy import URL
url = URL.create("postgresql+psycopg2", username="scott", password="P@ss%rd", host="localhost")sqlalchemy.url = postgresql+psycopg2://user:pass@localhost/mydb%import urllib.parse
from sqlalchemy import URL
url = URL.create("postgresql+psycopg2", username="scott", password="P@ss%rd", host="localhost")
**Never hard-code production credentials.** Read the URL from an environment variable in `env.py` instead:
```python
**切勿硬编码生产环境凭据**。请改为在`env.py`中从环境变量读取URL:
```pythonundefinedundefinedenv.pyenv.pyMetaDataundefinedMetaDataundefinedundefinedundefinedMetaDatafrom sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
metadata = MetaData(naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
})unique=Trueindex=TrueMetaDatafrom sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
metadata = MetaData(naming_convention={
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_`%(constraint_name)s`",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
})unique=Trueindex=Trueundefinedundefined
**Always review autogenerated scripts** before running them. Autogenerate cannot detect: table renames, column renames, or anonymously named constraints.
**运行前务必检查自动生成的脚本**。自动生成无法检测:表重命名、列重命名或匿名命名的约束。"""add account table
Revision ID: 1975ea83b712
Revises: <previous_rev_id or None>
Create Date: 2024-01-15 10:30:00
"""
revision = '1975ea83b712'
down_revision = None # None = first migration
branch_labels = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'account',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('created_at', sa.DateTime, nullable=False),
)
def downgrade():
op.drop_table('account')downgrade()alembic downgrade"""add account table
Revision ID: 1975ea83b712
Revises: <previous_rev_id or None>
Create Date: 2024-01-15 10:30:00
"""
revision = '1975ea83b712'
down_revision = None # None = 首次迁移
branch_labels = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.create_table(
'account',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('created_at', sa.DateTime, nullable=False),
)
def downgrade():
op.drop_table('account')downgrade()alembic downgradeundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined
Use `alembic check` in CI pipelines to assert that all model changes have a corresponding migration committed.
在CI流水线中使用`alembic check`来确保所有模型变更都有对应的已提交迁移。alembic.ini[post_write_hooks]
hooks = ruff
ruff.type = exec
ruff.executable = ruff
ruff.options = check --fix REVISION_SCRIPT_FILENAMEpyproject.toml[[tool.alembic.post_write_hooks]]
name = "ruff"
type = "exec"
executable = "ruff"
options = "check --fix REVISION_SCRIPT_FILENAME"alembic.ini[post_write_hooks]
hooks = ruff
ruff.type = exec
ruff.executable = ruff
ruff.options = check --fix REVISION_SCRIPT_FILENAMEpyproject.toml[[tool.alembic.post_write_hooks]]
name = "ruff"
type = "exec"
executable = "ruff"
options = "check --fix REVISION_SCRIPT_FILENAME"| Command | Description |
|---|---|
| Initialize migration environment |
| Create empty revision |
| Generate revision from model diff |
| Apply all pending migrations |
| Roll back all migrations |
| Show current DB revision |
| List all revisions |
| Assert no pending migrations (CI) |
| 命令 | 描述 |
|---|---|
| 初始化迁移环境 |
| 创建空修订版本 |
| 从模型差异生成修订版本 |
| 应用所有待处理的迁移 |
| 回滚所有迁移 |
| 显示当前数据库修订版本 |
| 列出所有修订版本 |
| 断言无待处理迁移(适用于CI) |
MetaDatadowngrade()alembic checkpyprojectop.f()MetaDatadowngrade()alembic checkpyprojectop.f()references/env-configuration.mdenv.pyinclude_nameinclude_objectreferences/autogenerate-guide.mdalembic checkreferences/env-configuration.mdenv.pyinclude_nameinclude_objectreferences/autogenerate-guide.mdalembic check