revert(db): remove Alembic migration system

Remove Alembic database migration system in favor of delta scripts:

Deleted:
- runtime/datamate-python/alembic.ini (config file)
- runtime/datamate-python/alembic/env.py (environment config)
- runtime/datamate-python/alembic/script.py.mako (migration template)
- runtime/datamate-python/alembic/versions/20250205_0001_add_file_version.py (migration)

Modified:
- scripts/db/data-annotation-init.sql
  - Removed alembic_version table creation and version insertion
  - Kept file_version column in t_dm_annotation_results

Rationale:
- Alembic migration testing failed in production
- Delta scripts are simpler and more reliable for this project
- SQL init scripts contain complete schema including latest changes
This commit is contained in:
2026-02-06 13:29:44 +08:00
parent f8f9faaa06
commit fbc83b5610
5 changed files with 0 additions and 231 deletions

View File

@@ -1,40 +0,0 @@
[alembic]
script_location = alembic
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
prepend_sys_path = .
[post_write_hooks]
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S

View File

@@ -1,84 +0,0 @@
"""Alembic environment configuration
说明:
- DataMate Python 服务使用异步 SQLAlchemy(mysql+aiomysql)。
- 为了让 `alembic upgrade head` 开箱即用,这里自动从 `settings.database_url`
注入 `sqlalchemy.url`,无需在 alembic.ini 手工维护。
"""
from __future__ import annotations
import asyncio
import os
import sys
from logging.config import fileConfig
from alembic import context
from sqlalchemy import pool
from sqlalchemy.ext.asyncio import async_engine_from_config
# 添加项目路径(runtime/datamate-python)
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from app.core.config import settings
from app.db.session import Base
from app.db.models import * # noqa: F401,F403
config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# 自动注入 sqlalchemy.url(优先使用 settings.database_url)
if not config.get_main_option("sqlalchemy.url"):
config.set_main_option("sqlalchemy.url", settings.database_url)
target_metadata = Base.metadata
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode."""
url = config.get_main_option("sqlalchemy.url")
if not url:
raise RuntimeError("alembic 未配置 sqlalchemy.url,且无法从 settings.database_url 推导")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def do_run_migrations(connection) -> None:
context.configure(connection=connection, target_metadata=target_metadata)
with context.begin_transaction():
context.run_migrations()
async def run_async_migrations() -> None:
connectable = async_engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)
await connectable.dispose()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode."""
asyncio.run(run_async_migrations())
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()

View File

@@ -1,24 +0,0 @@
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
branch_labels = ${repr(branch_labels)}
depends_on = ${repr(depends_on)}
def upgrade() -> None:
${upgrades if upgrades else "pass"}
def downgrade() -> None:
${downgrades if downgrades else "pass"}

View File

@@ -1,67 +0,0 @@
"""add file_version to annotation_results
Revision ID: 20250205_0001
Revises:
Create Date: 2025-02-05 00:00:00.000000
说明:
- 此迁移脚本用于升级旧版本数据库(使用 2025-02-05 之前的 SQL 脚本初始化)
- 如果使用最新的 data-annotation-init.sql 初始化,此脚本会自动跳过
(因为 alembic_version 表已包含此版本记录)
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import inspect
# revision identifiers, used by Alembic.
revision = "20250205_0001"
down_revision = None
branch_labels = None
depends_on = None
def column_exists(table_name: str, column_name: str) -> bool:
"""检查表中是否已存在指定列"""
conn = op.get_bind()
inspector = inspect(conn)
columns = [col['name'] for col in inspector.get_columns(table_name)]
return column_name in columns
def upgrade() -> None:
"""
升级:添加 file_version 字段到 t_dm_annotation_results 表
兼容性处理:
- 如果字段已存在(使用最新 SQL 脚本初始化),则跳过
- 如果字段不存在(旧版本数据库),则添加字段
"""
if column_exists("t_dm_annotation_results", "file_version"):
# 字段已存在,说明使用的是最新 SQL 初始化脚本
# Alembic 会自动记录版本,无需重复添加字段
print("字段 file_version 已存在,跳过添加操作(使用最新 SQL 脚本初始化)")
return
# 字段不存在,添加字段(旧版本数据库升级)
op.add_column(
"t_dm_annotation_results",
sa.Column(
"file_version", sa.BigInteger(), nullable=True, comment="标注时的文件版本号"
),
)
print("成功添加 file_version 字段到 t_dm_annotation_results 表")
def downgrade() -> None:
"""
回滚:删除 file_version 字段
注意:如果使用的是最新 SQL 脚本初始化,回滚此迁移不会删除字段
因为字段是初始结构的一部分
"""
if column_exists("t_dm_annotation_results", "file_version"):
op.drop_column("t_dm_annotation_results", "file_version")
print("成功删除 file_version 字段")