From ecba3d85282b5136dab65627cf5cf773cb31647d Mon Sep 17 00:00:00 2001 From: Audit Bot Date: Mon, 29 Jun 2026 12:57:49 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=20main=20=E5=88=86?= =?UTF-8?q?=E6=94=AF=E6=AE=8B=E7=95=99=E7=9A=84=20010=5Fadd=5Fforeign=5Fke?= =?UTF-8?q?y=5Fconstraints.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 该文件来自旧 PR#65,与 develop 分支的 010_phase0_extensibility.py 共用 revision '010' 且都指向 down_revision '009',导致 alembic 双头问题。 develop 分支从未包含此文件,删除后迁移链恢复为单链: 001 → 002 → ... → 009 → 010(phase0_extensibility) → 011 → 012 → 013 验证: alembic heads 显示唯一 head 013 --- .../010_add_foreign_key_constraints.py | 190 ------------------ 1 file changed, 190 deletions(-) delete mode 100644 alembic/versions/010_add_foreign_key_constraints.py diff --git a/alembic/versions/010_add_foreign_key_constraints.py b/alembic/versions/010_add_foreign_key_constraints.py deleted file mode 100644 index ce6ca3870..000000000 --- a/alembic/versions/010_add_foreign_key_constraints.py +++ /dev/null @@ -1,190 +0,0 @@ -"""add foreign key constraints and missing indexes - -Revision ID: 010 -Revises: 009 -Create Date: 2026-06-28 - -Summary: -- Add ForeignKey constraints to all 35 logical FK columns across 16 tables -- ON DELETE CASCADE for parent-child relationships (project → children) -- ON DELETE SET NULL for optional user references (created_by, assignee, etc.) -- Add missing indexes on 10 FK columns -- Alter columns from NOT NULL to nullable where SET NULL is needed -""" - -from alembic import op -import sqlalchemy as sa - -revision = "010" -down_revision = "009" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - # ── projects ────────────────────────────────────────────── - op.create_foreign_key("fk_projects_owner_user_id", "projects", "users", ["owner_user_id"], ["id"], ondelete="CASCADE") - - # ── asset_libraries ─────────────────────────────────────── - op.create_foreign_key("fk_asset_libraries_project_id", "asset_libraries", "projects", ["project_id"], ["id"], ondelete="CASCADE") - - # ── assets ──────────────────────────────────────────────── - # uploaded_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("assets", "uploaded_by_user_id", existing_type=sa.String(36), nullable=True) - op.create_foreign_key("fk_assets_project_id", "assets", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_assets_asset_library_id", "assets", "asset_libraries", ["asset_library_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_assets_uploaded_by_user_id", "assets", "users", ["uploaded_by_user_id"], ["id"], ondelete="SET NULL") - # Add missing index - op.create_index("ix_assets_uploaded_by_user_id", "assets", ["uploaded_by_user_id"]) - - # ── project_titles ──────────────────────────────────────── - # created_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("project_titles", "created_by_user_id", existing_type=sa.String(36), nullable=True) - op.create_foreign_key("fk_project_titles_project_id", "project_titles", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_project_titles_created_by_user_id", "project_titles", "users", ["created_by_user_id"], ["id"], ondelete="SET NULL") - # Add missing index - op.create_index("ix_project_titles_created_by_user_id", "project_titles", ["created_by_user_id"]) - - # ── edit_templates ──────────────────────────────────────── - # created_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("edit_templates", "created_by_user_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_edit_templates_project_id", "edit_templates", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_edit_templates_created_by_user_id", "edit_templates", "users", ["created_by_user_id"], ["id"], ondelete="SET NULL") - - # ── edit_plans ──────────────────────────────────────────── - # title_id: nullable=False → nullable=True for SET NULL - # created_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("edit_plans", "title_id", existing_type=sa.String(32), nullable=True) - op.alter_column("edit_plans", "created_by_user_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_edit_plans_project_id", "edit_plans", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_edit_plans_template_id", "edit_plans", "edit_templates", ["template_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_edit_plans_asset_library_id", "edit_plans", "asset_libraries", ["asset_library_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_edit_plans_title_id", "edit_plans", "project_titles", ["title_id"], ["id"], ondelete="SET NULL") - op.create_foreign_key("fk_edit_plans_created_by_user_id", "edit_plans", "users", ["created_by_user_id"], ["id"], ondelete="SET NULL") - - # ── edit_plan_clips ─────────────────────────────────────── - op.create_foreign_key("fk_edit_plan_clips_edit_plan_id", "edit_plan_clips", "edit_plans", ["edit_plan_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_edit_plan_clips_asset_id", "edit_plan_clips", "assets", ["asset_id"], ["id"], ondelete="CASCADE") - - # ── ingest_jobs ─────────────────────────────────────────── - # result_asset_id: nullable=False → nullable=True for SET NULL - op.alter_column("ingest_jobs", "result_asset_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_ingest_jobs_project_id", "ingest_jobs", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_ingest_jobs_library_id", "ingest_jobs", "asset_libraries", ["library_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_ingest_jobs_result_asset_id", "ingest_jobs", "assets", ["result_asset_id"], ["id"], ondelete="SET NULL") - - # ── classification_jobs ─────────────────────────────────── - op.create_foreign_key("fk_classification_jobs_project_id", "classification_jobs", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_classification_jobs_asset_id", "classification_jobs", "assets", ["asset_id"], ["id"], ondelete="CASCADE") - - # ── generation_tasks ────────────────────────────────────── - # edit_plan_id: nullable=False → nullable=True for SET NULL - # created_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("generation_tasks", "edit_plan_id", existing_type=sa.String(32), nullable=True) - op.alter_column("generation_tasks", "created_by_user_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_generation_tasks_project_id", "generation_tasks", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_generation_tasks_asset_library_id", "generation_tasks", "asset_libraries", ["asset_library_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_generation_tasks_edit_plan_id", "generation_tasks", "edit_plans", ["edit_plan_id"], ["id"], ondelete="SET NULL") - op.create_foreign_key("fk_generation_tasks_created_by_user_id", "generation_tasks", "users", ["created_by_user_id"], ["id"], ondelete="SET NULL") - - # ── generated_videos ────────────────────────────────────── - op.create_foreign_key("fk_generated_videos_project_id", "generated_videos", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_generated_videos_generation_task_id", "generated_videos", "generation_tasks", ["generation_task_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_generated_videos_duplicate_of", "generated_videos", "generated_videos", ["duplicate_of"], ["id"], ondelete="SET NULL") - - # ── tasks ───────────────────────────────────────────────── - # parent_task_id: nullable=False → nullable=True for SET NULL - # assignee_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("tasks", "parent_task_id", existing_type=sa.String(32), nullable=True) - op.alter_column("tasks", "assignee_user_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_tasks_project_id", "tasks", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_tasks_parent_task_id", "tasks", "tasks", ["parent_task_id"], ["id"], ondelete="SET NULL") - op.create_foreign_key("fk_tasks_assignee_user_id", "tasks", "users", ["assignee_user_id"], ["id"], ondelete="SET NULL") - - # ── milestones ──────────────────────────────────────────── - op.create_foreign_key("fk_milestones_project_id", "milestones", "projects", ["project_id"], ["id"], ondelete="CASCADE") - - # ── task_issues ─────────────────────────────────────────── - # created_by_user_id: nullable=False → nullable=True for SET NULL - op.alter_column("task_issues", "created_by_user_id", existing_type=sa.String(32), nullable=True) - op.create_foreign_key("fk_task_issues_task_id", "task_issues", "tasks", ["task_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_task_issues_project_id", "task_issues", "projects", ["project_id"], ["id"], ondelete="CASCADE") - op.create_foreign_key("fk_task_issues_created_by_user_id", "task_issues", "users", ["created_by_user_id"], ["id"], ondelete="SET NULL") - - -def downgrade() -> None: - # ── task_issues ─────────────────────────────────────────── - op.drop_constraint("fk_task_issues_created_by_user_id", "task_issues", type_="foreignkey") - op.drop_constraint("fk_task_issues_project_id", "task_issues", type_="foreignkey") - op.drop_constraint("fk_task_issues_task_id", "task_issues", type_="foreignkey") - op.alter_column("task_issues", "created_by_user_id", existing_type=sa.String(32), nullable=False) - - # ── milestones ──────────────────────────────────────────── - op.drop_constraint("fk_milestones_project_id", "milestones", type_="foreignkey") - - # ── tasks ───────────────────────────────────────────────── - op.drop_constraint("fk_tasks_assignee_user_id", "tasks", type_="foreignkey") - op.drop_constraint("fk_tasks_parent_task_id", "tasks", type_="foreignkey") - op.drop_constraint("fk_tasks_project_id", "tasks", type_="foreignkey") - op.alter_column("tasks", "assignee_user_id", existing_type=sa.String(32), nullable=False) - op.alter_column("tasks", "parent_task_id", existing_type=sa.String(32), nullable=False) - - # ── generated_videos ────────────────────────────────────── - op.drop_constraint("fk_generated_videos_duplicate_of", "generated_videos", type_="foreignkey") - op.drop_constraint("fk_generated_videos_generation_task_id", "generated_videos", type_="foreignkey") - op.drop_constraint("fk_generated_videos_project_id", "generated_videos", type_="foreignkey") - - # ── generation_tasks ────────────────────────────────────── - op.drop_constraint("fk_generation_tasks_created_by_user_id", "generation_tasks", type_="foreignkey") - op.drop_constraint("fk_generation_tasks_edit_plan_id", "generation_tasks", type_="foreignkey") - op.drop_constraint("fk_generation_tasks_asset_library_id", "generation_tasks", type_="foreignkey") - op.drop_constraint("fk_generation_tasks_project_id", "generation_tasks", type_="foreignkey") - op.alter_column("generation_tasks", "created_by_user_id", existing_type=sa.String(32), nullable=False) - op.alter_column("generation_tasks", "edit_plan_id", existing_type=sa.String(32), nullable=False) - - # ── classification_jobs ─────────────────────────────────── - op.drop_constraint("fk_classification_jobs_asset_id", "classification_jobs", type_="foreignkey") - op.drop_constraint("fk_classification_jobs_project_id", "classification_jobs", type_="foreignkey") - - # ── ingest_jobs ─────────────────────────────────────────── - op.drop_constraint("fk_ingest_jobs_result_asset_id", "ingest_jobs", type_="foreignkey") - op.drop_constraint("fk_ingest_jobs_library_id", "ingest_jobs", type_="foreignkey") - op.drop_constraint("fk_ingest_jobs_project_id", "ingest_jobs", type_="foreignkey") - op.alter_column("ingest_jobs", "result_asset_id", existing_type=sa.String(32), nullable=False) - - # ── edit_plan_clips ─────────────────────────────────────── - op.drop_constraint("fk_edit_plan_clips_asset_id", "edit_plan_clips", type_="foreignkey") - op.drop_constraint("fk_edit_plan_clips_edit_plan_id", "edit_plan_clips", type_="foreignkey") - - # ── edit_plans ──────────────────────────────────────────── - op.drop_constraint("fk_edit_plans_created_by_user_id", "edit_plans", type_="foreignkey") - op.drop_constraint("fk_edit_plans_title_id", "edit_plans", type_="foreignkey") - op.drop_constraint("fk_edit_plans_asset_library_id", "edit_plans", type_="foreignkey") - op.drop_constraint("fk_edit_plans_template_id", "edit_plans", type_="foreignkey") - op.drop_constraint("fk_edit_plans_project_id", "edit_plans", type_="foreignkey") - op.alter_column("edit_plans", "created_by_user_id", existing_type=sa.String(32), nullable=False) - op.alter_column("edit_plans", "title_id", existing_type=sa.String(32), nullable=False) - - # ── edit_templates ──────────────────────────────────────── - op.drop_constraint("fk_edit_templates_created_by_user_id", "edit_templates", type_="foreignkey") - op.drop_constraint("fk_edit_templates_project_id", "edit_templates", type_="foreignkey") - op.alter_column("edit_templates", "created_by_user_id", existing_type=sa.String(32), nullable=False) - - # ── project_titles ──────────────────────────────────────── - op.drop_index("ix_project_titles_created_by_user_id", table_name="project_titles") - op.drop_constraint("fk_project_titles_created_by_user_id", "project_titles", type_="foreignkey") - op.drop_constraint("fk_project_titles_project_id", "project_titles", type_="foreignkey") - op.alter_column("project_titles", "created_by_user_id", existing_type=sa.String(36), nullable=False) - - # ── assets ──────────────────────────────────────────────── - op.drop_index("ix_assets_uploaded_by_user_id", table_name="assets") - op.drop_constraint("fk_assets_uploaded_by_user_id", "assets", type_="foreignkey") - op.drop_constraint("fk_assets_asset_library_id", "assets", type_="foreignkey") - op.drop_constraint("fk_assets_project_id", "assets", type_="foreignkey") - op.alter_column("assets", "uploaded_by_user_id", existing_type=sa.String(36), nullable=False) - - # ── asset_libraries ─────────────────────────────────────── - op.drop_constraint("fk_asset_libraries_project_id", "asset_libraries", type_="foreignkey") - - # ── projects ────────────────────────────────────────────── - op.drop_constraint("fk_projects_owner_user_id", "projects", type_="foreignkey") -- 2.54.0