From cbd40687767509646d129c9df87cdbbb0a5d141c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E9=B1=BC=E5=BC=80=E5=8F=91?= Date: Fri, 15 May 2026 18:28:07 +0800 Subject: [PATCH] fix(db): unify table name prefix to mjk_ for update tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename app_releases → mjk_app_releases - Rename release_packages → mjk_release_packages - Update ForeignKey reference and migration file - Add pre-commit hook: check_table_prefix.py to prevent future violations --- python-api/.pre-commit-config.yaml | 10 ++++ .../versions/c3a0e1c71ce6_initial_schema.py | 14 +++--- python-api/app/models/update.py | 6 +-- python-api/scripts/check_table_prefix.py | 46 +++++++++++++++++++ 4 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 python-api/scripts/check_table_prefix.py diff --git a/python-api/.pre-commit-config.yaml b/python-api/.pre-commit-config.yaml index f54e288..e96fa09 100644 --- a/python-api/.pre-commit-config.yaml +++ b/python-api/.pre-commit-config.yaml @@ -41,3 +41,13 @@ repos: language: system files: ^(pyproject\.toml|requirements\.lock)$ pass_filenames: false + + # 模型表名前缀一致性检查 + - repo: local + hooks: + - id: table-prefix-check + name: Check model __tablename__ has mjk_ prefix + entry: python scripts/check_table_prefix.py + language: system + files: ^app/models/.*\.py$ + pass_filenames: false diff --git a/python-api/alembic/versions/c3a0e1c71ce6_initial_schema.py b/python-api/alembic/versions/c3a0e1c71ce6_initial_schema.py index 1d04170..e3d7674 100644 --- a/python-api/alembic/versions/c3a0e1c71ce6_initial_schema.py +++ b/python-api/alembic/versions/c3a0e1c71ce6_initial_schema.py @@ -21,7 +21,7 @@ depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: """Upgrade schema.""" # ### commands auto generated by Alembic - please adjust! ### - op.create_table('app_releases', + op.create_table('mjk_app_releases', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('version', sa.String(length=20), nullable=False), sa.Column('release_date', sa.DateTime(timezone=True), nullable=False), @@ -30,7 +30,7 @@ def upgrade() -> None: sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), sa.PrimaryKeyConstraint('id') ) - op.create_index(op.f('ix_app_releases_version'), 'app_releases', ['version'], unique=True) + op.create_index(op.f('ix_mjk_app_releases_version'), 'mjk_app_releases', ['version'], unique=True) op.create_table('mjk_broll_categories', sa.Column('slug', sa.String(length=128), nullable=False, comment='分类标识符,URL友好格式'), sa.Column('name', sa.String(length=256), nullable=False, comment='分类中文名称,三级分类直接对应 scene 标准化后的值'), @@ -178,7 +178,7 @@ def upgrade() -> None: sa.ForeignKeyConstraint(['category_id'], ['mjk_broll_categories.id'], ), sa.PrimaryKeyConstraint('id') ) - op.create_table('release_packages', + op.create_table('mjk_release_packages', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('release_id', sa.Integer(), nullable=False), sa.Column('platform', sa.String(length=20), nullable=False), @@ -189,7 +189,7 @@ def upgrade() -> None: sa.Column('signature', sa.Text(), nullable=False), sa.Column('download_count', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(timezone=True), nullable=False), - sa.ForeignKeyConstraint(['release_id'], ['app_releases.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['release_id'], ['mjk_app_releases.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('release_id', 'platform', 'architecture', name='uix_pkg_platform_arch') ) @@ -199,7 +199,7 @@ def upgrade() -> None: def downgrade() -> None: """Downgrade schema.""" # ### commands auto generated by Alembic - please adjust! ### - op.drop_table('release_packages') + op.drop_table('mjk_release_packages') op.drop_table('mjk_broll_materials') op.drop_table('mjk_users') op.drop_table('mjk_user_points') @@ -210,6 +210,6 @@ def downgrade() -> None: op.drop_table('mjk_cover_backgrounds') op.drop_table('mjk_broll_tags') op.drop_table('mjk_broll_categories') - op.drop_index(op.f('ix_app_releases_version'), table_name='app_releases') - op.drop_table('app_releases') + op.drop_index(op.f('ix_mjk_app_releases_version'), table_name='mjk_app_releases') + op.drop_table('mjk_app_releases') # ### end Alembic commands ### diff --git a/python-api/app/models/update.py b/python-api/app/models/update.py index 0a9c459..0f89127 100644 --- a/python-api/app/models/update.py +++ b/python-api/app/models/update.py @@ -16,7 +16,7 @@ from app.db.session import Base class AppRelease(Base): """应用版本发布记录""" - __tablename__ = "app_releases" + __tablename__ = "mjk_app_releases" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) version: Mapped[str] = mapped_column(String(20), unique=True, nullable=False, index=True) @@ -38,12 +38,12 @@ class AppRelease(Base): class ReleasePackage(Base): """平台安装包信息""" - __tablename__ = "release_packages" + __tablename__ = "mjk_release_packages" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) release_id: Mapped[int] = mapped_column( Integer, - ForeignKey("app_releases.id", ondelete="CASCADE"), + ForeignKey("mjk_app_releases.id", ondelete="CASCADE"), nullable=False, ) platform: Mapped[str] = mapped_column(String(20), nullable=False) diff --git a/python-api/scripts/check_table_prefix.py b/python-api/scripts/check_table_prefix.py new file mode 100644 index 0000000..a6beb8c --- /dev/null +++ b/python-api/scripts/check_table_prefix.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +检查所有模型的 __tablename__ 是否以 mjk_ 开头 + +用法: + python scripts/check_table_prefix.py + +退出码: + 0 - 所有表名合规 + 1 - 有表名缺少 mjk_ 前缀 +""" + +import re +import sys +from pathlib import Path + + +MODELS_DIR = Path("app/models") +TABLENAME_RE = re.compile(r'__tablename__\s*=\s*"([^"]+)"') + + +def check() -> int: + violations = [] + + for py_file in sorted(MODELS_DIR.glob("*.py")): + content = py_file.read_text(encoding="utf-8") + for match in TABLENAME_RE.finditer(content): + table_name = match.group(1) + if not table_name.startswith("mjk_"): + violations.append((py_file.name, table_name)) + + if violations: + print("❌ 表名前缀检查失败:以下模型的 __tablename__ 缺少 'mjk_' 前缀\n") + for filename, table_name in violations: + print(f" {filename}: __tablename__ = \"{table_name}\"") + print( + "\n修复方式:将表名改为 mjk_ 格式,与其他模型保持一致。\n" + ) + return 1 + + print("✅ 所有模型表名均以 'mjk_' 开头") + return 0 + + +if __name__ == "__main__": + sys.exit(check())