1217d8cef0
Deploy / Build Production Runtime Images (push) Has been skipped
Deploy / Deploy Production (push) Has been skipped
Deploy / Production Browser E2E (push) Has been skipped
Deploy / Deploy Staging (push) Failing after 210h35m44s
CI/CD Pipeline / Frontend Lint (push) Failing after 210h36m11s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 210h36m17s
72 lines
2.3 KiB
Python
72 lines
2.3 KiB
Python
"""Phase 2 - 查重功能:duplication_records + duplication_segments
|
|
|
|
Revision ID: 012
|
|
Revises: 011
|
|
Create Date: 2026-06-28
|
|
|
|
This migration creates two new tables:
|
|
1. duplication_records — 查重记录主表
|
|
2. duplication_segments — 重复片段详情表
|
|
"""
|
|
|
|
import sqlalchemy as sa
|
|
|
|
from alembic import op
|
|
|
|
# revision identifiers
|
|
revision = "012"
|
|
down_revision = "011"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
conn = op.get_bind()
|
|
|
|
# ── 1. Create duplication_records table ──
|
|
|
|
conn.execute(sa.text("""
|
|
CREATE TABLE IF NOT EXISTS duplication_records (
|
|
id VARCHAR(36) PRIMARY KEY,
|
|
user_id VARCHAR(36) NOT NULL,
|
|
filename VARCHAR(500) NOT NULL,
|
|
file_size INTEGER NOT NULL,
|
|
storage_key VARCHAR(500) NOT NULL,
|
|
duration_seconds FLOAT NOT NULL DEFAULT 0,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
duplicate_rate FLOAT,
|
|
duplicate_count INTEGER NOT NULL DEFAULT 0,
|
|
video_fingerprint TEXT,
|
|
error_message TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
)
|
|
"""))
|
|
conn.execute(sa.text("CREATE INDEX IF NOT EXISTS ix_duplication_records_user_id ON duplication_records(user_id)"))
|
|
conn.execute(sa.text("CREATE INDEX IF NOT EXISTS ix_duplication_records_status ON duplication_records(status)"))
|
|
|
|
# ── 2. Create duplication_segments table ──
|
|
|
|
conn.execute(sa.text("""
|
|
CREATE TABLE IF NOT EXISTS duplication_segments (
|
|
id VARCHAR(36) PRIMARY KEY,
|
|
record_id VARCHAR(36) NOT NULL,
|
|
source_start FLOAT NOT NULL,
|
|
source_end FLOAT NOT NULL,
|
|
matched_video_id VARCHAR(36) NOT NULL,
|
|
matched_video_name VARCHAR(500) NOT NULL DEFAULT '',
|
|
matched_start FLOAT NOT NULL,
|
|
matched_end FLOAT NOT NULL,
|
|
similarity FLOAT NOT NULL
|
|
)
|
|
"""))
|
|
conn.execute(
|
|
sa.text("CREATE INDEX IF NOT EXISTS ix_duplication_segments_record_id ON duplication_segments(record_id)")
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
conn = op.get_bind()
|
|
conn.execute(sa.text("DROP TABLE IF EXISTS duplication_segments"))
|
|
conn.execute(sa.text("DROP TABLE IF EXISTS duplication_records"))
|