merge main
This commit is contained in:
@@ -0,0 +1,654 @@
|
||||
"""2026073101_add_column_comments
|
||||
|
||||
Revision ID: 2026073101
|
||||
Revises: f7g8h9i0j1k2
|
||||
Create Date: 2026-07-31 00:00:00.000000
|
||||
|
||||
该文件包含 2026-07-31 的数据库迁移内容:
|
||||
给所有表字段添加 COMMENT 注释,便于数据库维护与排查。
|
||||
仅使用 COMMENT ON COLUMN/COMMENT ON TABLE 语句,不修改列类型与约束。
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
revision: str = '2026073101'
|
||||
down_revision: Union[str, None] = 'f7g8h9i0j1k2'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def _comment_table(table_name: str, comment: str) -> None:
|
||||
op.execute(f"COMMENT ON TABLE {table_name} IS '{comment}'")
|
||||
|
||||
|
||||
def _comment_column(table_name: str, column_name: str, comment: str) -> None:
|
||||
escaped = comment.replace("'", "''")
|
||||
op.execute(f"COMMENT ON COLUMN {table_name}.{column_name} IS '{escaped}'")
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ============================================================
|
||||
# users 表
|
||||
# ============================================================
|
||||
_comment_table("users", "用户表")
|
||||
_comment_column("users", "id", "主键ID")
|
||||
_comment_column("users", "username", "用户名,唯一")
|
||||
_comment_column("users", "email", "邮箱,唯一")
|
||||
_comment_column("users", "phone", "手机号,唯一")
|
||||
_comment_column("users", "hashed_password", "加密后的密码")
|
||||
_comment_column("users", "avatar", "头像URL")
|
||||
_comment_column("users", "credits", "账户积分余额")
|
||||
_comment_column("users", "is_active", "是否启用,True启用")
|
||||
_comment_column("users", "is_admin", "是否管理员,True管理员")
|
||||
_comment_column("users", "user_type", "用户类型:frontend前台用户,admin后台管理员")
|
||||
_comment_column("users", "frontend_user_kind", "前台用户类型:internal内部用户,external外部用户")
|
||||
_comment_column("users", "team_id", "当前归属团队ID,仅前台用户有意义")
|
||||
_comment_column("users", "last_login_at", "最后登录时间")
|
||||
_comment_column("users", "password_set_at", "密码设置时间,NULL表示未设置密码")
|
||||
_comment_column("users", "allowed_menus", "允许访问的菜单列表(JSON),NULL表示继承默认")
|
||||
_comment_column("users", "private_portrait_asset_limit", "私域人像素材总量上限,0表示关闭模块")
|
||||
_comment_column("users", "created_at", "创建时间")
|
||||
_comment_column("users", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# projects 表
|
||||
# ============================================================
|
||||
_comment_table("projects", "项目表")
|
||||
_comment_column("projects", "id", "主键ID")
|
||||
_comment_column("projects", "user_id", "所属用户ID")
|
||||
_comment_column("projects", "name", "项目名称")
|
||||
_comment_column("projects", "industry", "所属行业")
|
||||
_comment_column("projects", "created_at", "创建时间")
|
||||
_comment_column("projects", "updated_at", "更新时间")
|
||||
_comment_column("projects", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# credit_ratios 表
|
||||
# ============================================================
|
||||
_comment_table("credit_ratios", "积分计费规则表")
|
||||
_comment_column("credit_ratios", "id", "主键ID")
|
||||
_comment_column("credit_ratios", "model_config_id", "引擎ID:图片对应image_engines.id,视频对应video_engines.id")
|
||||
_comment_column("credit_ratios", "gen_type", "生成类型:image图片,video视频")
|
||||
_comment_column("credit_ratios", "resolution", "分辨率档位:图片(2K/4K) / 视频(480p/720p/1080p)")
|
||||
_comment_column("credit_ratios", "ratio", "生成倍率,最终积分 = (基础积分+单位积分×时长/张数) × 倍率")
|
||||
_comment_column("credit_ratios", "base_credits", "生成基础积分")
|
||||
_comment_column("credit_ratios", "per_second_credits", "视频每秒积分 / 图片每张积分")
|
||||
_comment_column("credit_ratios", "input_video_ratio", "传入视频积分倍率")
|
||||
_comment_column("credit_ratios", "input_video_base_credits", "传入视频基础积分")
|
||||
_comment_column("credit_ratios", "input_video_per_second_credits", "传入视频每秒积分")
|
||||
_comment_column("credit_ratios", "input_image_ratio", "传入图片积分倍率")
|
||||
_comment_column("credit_ratios", "input_image_base_credits", "传入图片基础积分")
|
||||
_comment_column("credit_ratios", "input_image_per_image_credits", "传入图片每张积分")
|
||||
_comment_column("credit_ratios", "created_at", "创建时间")
|
||||
_comment_column("credit_ratios", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# credit_records 表
|
||||
# ============================================================
|
||||
_comment_table("credit_records", "积分流水表")
|
||||
_comment_column("credit_records", "id", "主键ID")
|
||||
_comment_column("credit_records", "user_id", "所属用户ID")
|
||||
_comment_column("credit_records", "type", "流水类型:charge扣费,recharge充值,refund退款,gift赠送")
|
||||
_comment_column("credit_records", "amount", "流水金额,扣费为负数,充值/退款/赠送为正数")
|
||||
_comment_column("credit_records", "balance_after", "流水后账户余额")
|
||||
_comment_column("credit_records", "description", "流水描述")
|
||||
_comment_column("credit_records", "related_id", "关联业务ID,如生成任务ID/订单ID")
|
||||
_comment_column("credit_records", "biz_key", "业务幂等键,格式如 owner_type:owner_id:attempt_no:charge_kind:action")
|
||||
_comment_column("credit_records", "refund_for_biz_key", "退款时,对应的扣费biz_key")
|
||||
_comment_column("credit_records", "owner_type", "归属类型:chat_generation_task/ generation_record等")
|
||||
_comment_column("credit_records", "owner_id", "归属业务记录ID")
|
||||
_comment_column("credit_records", "attempt_no", "计费尝试次数,重试时递增")
|
||||
_comment_column("credit_records", "charge_kind", "扣费大类:media媒体生成,prompt提示词等")
|
||||
_comment_column("credit_records", "charge_action", "扣费动作:charge扣费,refund退款")
|
||||
_comment_column("credit_records", "credit_subject", "计费科目:image/video/text")
|
||||
_comment_column("credit_records", "media_type", "媒体类型:与credit_subject配合细分")
|
||||
_comment_column("credit_records", "billing_scene", "计费场景:如chat_creation、project等")
|
||||
_comment_column("credit_records", "source_module", "来源模块:generation_record/module_generation等")
|
||||
_comment_column("credit_records", "source_project_id", "来源项目ID")
|
||||
_comment_column("credit_records", "source_step_id", "来源步骤ID")
|
||||
_comment_column("credit_records", "source_step_code", "来源步骤编码")
|
||||
_comment_column("credit_records", "token_usage_id", "关联Token消耗记录ID")
|
||||
_comment_column("credit_records", "input_tokens", "输入Token数量快照")
|
||||
_comment_column("credit_records", "output_tokens", "输出Token数量快照")
|
||||
_comment_column("credit_records", "total_tokens", "总Token数量快照")
|
||||
_comment_column("credit_records", "engine_type", "引擎类型:image/video/text")
|
||||
_comment_column("credit_records", "engine_id", "使用的引擎ID")
|
||||
_comment_column("credit_records", "engine_name", "引擎名称快照")
|
||||
_comment_column("credit_records", "engine_provider", "引擎供应商快照:ark/其他")
|
||||
_comment_column("credit_records", "engine_model_name", "引擎模型名快照")
|
||||
_comment_column("credit_records", "user_type_snapshot", "用户类型快照:frontend/admin")
|
||||
_comment_column("credit_records", "frontend_user_kind_snapshot", "前台用户类型快照:internal/external")
|
||||
_comment_column("credit_records", "team_id_snapshot", "团队ID快照,流水发生时的归属团队")
|
||||
_comment_column("credit_records", "team_name_snapshot", "团队名称快照")
|
||||
_comment_column("credit_records", "created_at", "创建时间")
|
||||
_comment_column("credit_records", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# chat_generation_tasks 表
|
||||
# ============================================================
|
||||
_comment_table("chat_generation_tasks", "AI创作任务表(不绑定项目的聊天式生成)")
|
||||
_comment_column("chat_generation_tasks", "id", "主键ID,顶层/子任务ID")
|
||||
_comment_column("chat_generation_tasks", "user_id", "所属用户ID")
|
||||
_comment_column("chat_generation_tasks", "original_prompt", "原始用户提示词")
|
||||
_comment_column("chat_generation_tasks", "optimized_prompt", "优化后的提示词")
|
||||
_comment_column("chat_generation_tasks", "gen_type", "生成类型:image图片,video视频")
|
||||
_comment_column("chat_generation_tasks", "duration", "视频时长(秒)")
|
||||
_comment_column("chat_generation_tasks", "aspect_ratio", "视频比例:16:9/9:16等")
|
||||
_comment_column("chat_generation_tasks", "resolution", "用户选择的分辨率")
|
||||
_comment_column("chat_generation_tasks", "provider_generation_resolution", "供应商实际生成分辨率")
|
||||
_comment_column("chat_generation_tasks", "video_upscale_enabled_snapshot", "是否开启视频超分")
|
||||
_comment_column("chat_generation_tasks", "video_upscale_snapshot_json", "视频超分参数快照JSON")
|
||||
_comment_column("chat_generation_tasks", "image_size", "图片分辨率档位:2K/4K")
|
||||
_comment_column("chat_generation_tasks", "image_proportion", "图片比例:1:1/16:9等")
|
||||
_comment_column("chat_generation_tasks", "image_px", "图片像素,如2048×2048")
|
||||
_comment_column("chat_generation_tasks", "status", "任务状态:generating/success/failed等")
|
||||
_comment_column("chat_generation_tasks", "pipeline_stage", "流水线阶段:prompt_optimized/resource_generated等")
|
||||
_comment_column("chat_generation_tasks", "generation_mode", "生成模式:chatapi_async单份异步/chatapi_main多份主任务")
|
||||
_comment_column("chat_generation_tasks", "parent_task_id", "父任务ID,多份生成时子任务关联主任务")
|
||||
_comment_column("chat_generation_tasks", "generation_count", "生成份数,主任务表示总共多少份")
|
||||
_comment_column("chat_generation_tasks", "generation_index", "第N份子任务,主任务为NULL")
|
||||
_comment_column("chat_generation_tasks", "generation_attempt_no", "生成尝试次数,重试时递增")
|
||||
_comment_column("chat_generation_tasks", "resource_generation_started_at", "资源生成开始时间")
|
||||
_comment_column("chat_generation_tasks", "provider_create_claim_token", "供应商创建任务分布式租约token")
|
||||
_comment_column("chat_generation_tasks", "provider_create_lease_until", "供应商创建租约过期时间")
|
||||
_comment_column("chat_generation_tasks", "provider_create_started_at", "供应商创建任务开始时间")
|
||||
_comment_column("chat_generation_tasks", "media_references", "参考素材JSON数组")
|
||||
_comment_column("chat_generation_tasks", "provider_task_id", "供应商任务ID")
|
||||
_comment_column("chat_generation_tasks", "seedance_task_id", "Seedance任务ID(兼容字段)")
|
||||
_comment_column("chat_generation_tasks", "remote_result_url", "供应商返回的远程资源URL")
|
||||
_comment_column("chat_generation_tasks", "image_url", "图片结果URL")
|
||||
_comment_column("chat_generation_tasks", "video_url", "视频结果URL")
|
||||
_comment_column("chat_generation_tasks", "video_cover_url", "视频封面URL")
|
||||
_comment_column("chat_generation_tasks", "engine_id", "使用的引擎ID")
|
||||
_comment_column("chat_generation_tasks", "engine_snapshot_json", "引擎参数快照JSON")
|
||||
_comment_column("chat_generation_tasks", "provider_response_json", "供应商完整响应JSON")
|
||||
_comment_column("chat_generation_tasks", "credits_cost", "媒体生成消耗的总积分")
|
||||
_comment_column("chat_generation_tasks", "text_credits_cost", "提示词优化消耗积分")
|
||||
_comment_column("chat_generation_tasks", "text_tokens_used", "提示词优化Token消耗")
|
||||
_comment_column("chat_generation_tasks", "video_tokens_used", "视频生成Token消耗")
|
||||
_comment_column("chat_generation_tasks", "image_tokens_used", "图片生成Token消耗")
|
||||
_comment_column("chat_generation_tasks", "retry_count", "重试次数(兼容旧字段)")
|
||||
_comment_column("chat_generation_tasks", "manual_retry_count", "用户手动重试次数")
|
||||
_comment_column("chat_generation_tasks", "poll_error_count", "轮询错误次数")
|
||||
_comment_column("chat_generation_tasks", "poll_count", "轮询总次数")
|
||||
_comment_column("chat_generation_tasks", "last_poll_at", "最后一次轮询时间")
|
||||
_comment_column("chat_generation_tasks", "poll_started_at", "本次轮询开始时间")
|
||||
_comment_column("chat_generation_tasks", "next_poll_at", "下一次轮询触发时间")
|
||||
_comment_column("chat_generation_tasks", "poll_interval_seconds", "轮询间隔秒数")
|
||||
_comment_column("chat_generation_tasks", "poll_claim_token", "轮询分布式租约token")
|
||||
_comment_column("chat_generation_tasks", "poll_lease_until", "轮询租约过期时间")
|
||||
_comment_column("chat_generation_tasks", "deadline_at", "任务截止时间,超时自动失败")
|
||||
_comment_column("chat_generation_tasks", "generated_at", "资源生成完成时间")
|
||||
_comment_column("chat_generation_tasks", "error_message", "错误信息")
|
||||
_comment_column("chat_generation_tasks", "idempotency_key", "幂等键,防重复创建")
|
||||
_comment_column("chat_generation_tasks", "download_celery_task_id", "下载步骤Celery任务ID")
|
||||
_comment_column("chat_generation_tasks", "download_enqueued_at", "下载入队时间")
|
||||
_comment_column("chat_generation_tasks", "download_started_at", "下载开始时间")
|
||||
_comment_column("chat_generation_tasks", "download_claim_token", "下载租约token")
|
||||
_comment_column("chat_generation_tasks", "download_lease_until", "下载租约过期时间")
|
||||
_comment_column("chat_generation_tasks", "download_next_retry_at", "下载下次重试时间")
|
||||
_comment_column("chat_generation_tasks", "download_attempt_count", "下载重试次数")
|
||||
_comment_column("chat_generation_tasks", "download_last_error", "下载最后一次错误信息")
|
||||
_comment_column("chat_generation_tasks", "download_storage_date_dir", "下载存储日期目录")
|
||||
_comment_column("chat_generation_tasks", "created_at", "创建时间")
|
||||
_comment_column("chat_generation_tasks", "updated_at", "更新时间")
|
||||
_comment_column("chat_generation_tasks", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# generation_records 表
|
||||
# ============================================================
|
||||
_comment_table("generation_records", "项目生成记录表(绑定项目的旧版生成)")
|
||||
_comment_column("generation_records", "id", "主键ID")
|
||||
_comment_column("generation_records", "user_id", "所属用户ID")
|
||||
_comment_column("generation_records", "project_id", "所属项目ID")
|
||||
_comment_column("generation_records", "original_prompt", "原始提示词")
|
||||
_comment_column("generation_records", "optimized_prompt", "优化后的提示词")
|
||||
_comment_column("generation_records", "prompt_usage_snapshot_json", "提示词消耗快照JSON")
|
||||
_comment_column("generation_records", "gen_type", "生成类型:image/video")
|
||||
_comment_column("generation_records", "duration", "视频时长秒数")
|
||||
_comment_column("generation_records", "aspect_ratio", "视频比例")
|
||||
_comment_column("generation_records", "resolution", "分辨率档位")
|
||||
_comment_column("generation_records", "provider_generation_resolution", "供应商实际分辨率")
|
||||
_comment_column("generation_records", "video_upscale_enabled_snapshot", "是否开启视频超分")
|
||||
_comment_column("generation_records", "video_upscale_snapshot_json", "视频超分快照JSON")
|
||||
_comment_column("generation_records", "image_size", "图片分辨率档位")
|
||||
_comment_column("generation_records", "image_proportion", "图片比例")
|
||||
_comment_column("generation_records", "image_px", "图片像素尺寸")
|
||||
_comment_column("generation_records", "status", "任务状态")
|
||||
_comment_column("generation_records", "pipeline_stage", "流水线阶段")
|
||||
_comment_column("generation_records", "video_url", "视频结果URL")
|
||||
_comment_column("generation_records", "video_cover_url", "视频封面URL")
|
||||
_comment_column("generation_records", "image_url", "图片结果URL")
|
||||
_comment_column("generation_records", "media_references", "参考素材JSON数组")
|
||||
_comment_column("generation_records", "include_media_references", "是否包含参考素材")
|
||||
_comment_column("generation_records", "video_url_expires_at", "视频URL过期时间")
|
||||
_comment_column("generation_records", "seedance_task_id", "Seedance任务ID")
|
||||
_comment_column("generation_records", "credits_cost", "媒体生成消耗积分")
|
||||
_comment_column("generation_records", "text_credits_cost", "提示词消耗积分")
|
||||
_comment_column("generation_records", "text_tokens_used", "提示词Token数")
|
||||
_comment_column("generation_records", "video_tokens_used", "视频Token数")
|
||||
_comment_column("generation_records", "image_tokens_used", "图片Token数")
|
||||
_comment_column("generation_records", "generated_at", "生成完成时间")
|
||||
_comment_column("generation_records", "error_message", "错误信息")
|
||||
_comment_column("generation_records", "idempotency_key", "幂等键")
|
||||
_comment_column("generation_records", "generation_attempt_no", "生成尝试次数")
|
||||
_comment_column("generation_records", "resource_generation_started_at", "资源生成开始时间")
|
||||
_comment_column("generation_records", "deadline_at", "任务截止时间")
|
||||
_comment_column("generation_records", "engine_id", "使用引擎ID")
|
||||
_comment_column("generation_records", "engine_snapshot_json", "引擎参数快照JSON")
|
||||
_comment_column("generation_records", "provider_response_json", "供应商响应JSON")
|
||||
_comment_column("generation_records", "remote_result_url", "远程资源URL")
|
||||
_comment_column("generation_records", "provider_create_claim_token", "供应商创建租约token")
|
||||
_comment_column("generation_records", "provider_create_lease_until", "供应商创建租约过期")
|
||||
_comment_column("generation_records", "provider_create_started_at", "供应商创建开始时间")
|
||||
_comment_column("generation_records", "retry_count", "重试次数(兼容)")
|
||||
_comment_column("generation_records", "manual_retry_count", "手动重试次数")
|
||||
_comment_column("generation_records", "poll_error_count", "轮询错误次数")
|
||||
_comment_column("generation_records", "poll_count", "轮询次数")
|
||||
_comment_column("generation_records", "last_poll_at", "最后轮询时间")
|
||||
_comment_column("generation_records", "poll_started_at", "轮询开始时间")
|
||||
_comment_column("generation_records", "next_poll_at", "下次轮询时间")
|
||||
_comment_column("generation_records", "poll_interval_seconds", "轮询间隔秒")
|
||||
_comment_column("generation_records", "poll_claim_token", "轮询租约token")
|
||||
_comment_column("generation_records", "poll_lease_until", "轮询租约过期")
|
||||
_comment_column("generation_records", "download_celery_task_id", "下载Celery任务ID")
|
||||
_comment_column("generation_records", "download_enqueued_at", "下载开始入队时间")
|
||||
_comment_column("generation_records", "download_started_at", "下载开始时间")
|
||||
_comment_column("generation_records", "download_claim_token", "下载租约token")
|
||||
_comment_column("generation_records", "download_lease_until", "下载租约过期")
|
||||
_comment_column("generation_records", "download_next_retry_at", "下载下次重试")
|
||||
_comment_column("generation_records", "download_attempt_count", "下载重试次数")
|
||||
_comment_column("generation_records", "download_last_error", "下载最后错误")
|
||||
_comment_column("generation_records", "download_storage_date_dir", "下载存储日期目录")
|
||||
_comment_column("generation_records", "created_at", "创建时间")
|
||||
_comment_column("generation_records", "updated_at", "更新时间")
|
||||
_comment_column("generation_records", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# generated_resources 表
|
||||
# ============================================================
|
||||
_comment_table("generated_resources", "生成资源账本表(统一记录所有生成的图片/视频)")
|
||||
_comment_column("generated_resources", "id", "主键ID")
|
||||
_comment_column("generated_resources", "user_id", "所属用户ID")
|
||||
_comment_column("generated_resources", "resource_type", "资源类型:image/video")
|
||||
_comment_column("generated_resources", "resource_url", "资源访问URL")
|
||||
_comment_column("generated_resources", "remote_url", "供应商原始远程URL")
|
||||
_comment_column("generated_resources", "storage_type", "存储类型:local本地/oss对象存储")
|
||||
_comment_column("generated_resources", "storage_path", "存储路径")
|
||||
_comment_column("generated_resources", "file_name", "文件名,平台素材名称")
|
||||
_comment_column("generated_resources", "file_size_bytes", "文件大小(字节)")
|
||||
_comment_column("generated_resources", "source_model", "来源模型:chat_generation_task/generation_record")
|
||||
_comment_column("generated_resources", "source_model_module", "来源模块描述")
|
||||
_comment_column("generated_resources", "source_id", "来源记录ID")
|
||||
_comment_column("generated_resources", "engine_id", "使用引擎ID")
|
||||
_comment_column("generated_resources", "engine_type", "引擎类型:image/video")
|
||||
_comment_column("generated_resources", "provider", "供应商:ark/其他")
|
||||
_comment_column("generated_resources", "model_name", "模型名称")
|
||||
_comment_column("generated_resources", "generated_at", "资源生成完成时间")
|
||||
_comment_column("generated_resources", "resource_month", "资源归属月份,按月统计")
|
||||
_comment_column("generated_resources", "extra_json", "扩展字段JSON")
|
||||
_comment_column("generated_resources", "created_at", "创建时间")
|
||||
_comment_column("generated_resources", "updated_at", "更新时间")
|
||||
_comment_column("generated_resources", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# upload_resources 表
|
||||
# ============================================================
|
||||
_comment_table("upload_resources", "用户上传资源账本表(用户上传/模块上传/切片文件)")
|
||||
_comment_column("upload_resources", "id", "主键ID")
|
||||
_comment_column("upload_resources", "user_id", "所属用户ID")
|
||||
_comment_column("upload_resources", "module", "所属模块:conversation/generation_record等")
|
||||
_comment_column("upload_resources", "resource_type", "资源类型:image/video/audio/file")
|
||||
_comment_column("upload_resources", "resource_url", "资源访问URL")
|
||||
_comment_column("upload_resources", "storage_path", "存储路径,唯一")
|
||||
_comment_column("upload_resources", "file_name", "原始文件名")
|
||||
_comment_column("upload_resources", "file_ext", "文件扩展名")
|
||||
_comment_column("upload_resources", "mime_type", "MIME类型")
|
||||
_comment_column("upload_resources", "file_size_bytes", "文件大小(字节)")
|
||||
_comment_column("upload_resources", "duration_seconds", "音视频时长(秒)")
|
||||
_comment_column("upload_resources", "duration_source", "时长来源:probe探测/用户设置")
|
||||
_comment_column("upload_resources", "width", "图片/视频宽度(像素)")
|
||||
_comment_column("upload_resources", "height", "图片/视频高度(像素)")
|
||||
_comment_column("upload_resources", "source_model", "关联业务模型")
|
||||
_comment_column("upload_resources", "source_id", "关联业务记录ID")
|
||||
_comment_column("upload_resources", "source_module", "关联业务模块")
|
||||
_comment_column("upload_resources", "bind_status", "绑定状态:pending待绑定/bound已绑定/unbound已解绑")
|
||||
_comment_column("upload_resources", "delete_policy", "删除策略:user_deletable用户可删/keep_forever永久保留")
|
||||
_comment_column("upload_resources", "created_by", "创建来源:api用户上传/worker系统生成")
|
||||
_comment_column("upload_resources", "metadata_json", "媒体元数据JSON")
|
||||
_comment_column("upload_resources", "capacity_released_at", "容量统计中已释放时间")
|
||||
_comment_column("upload_resources", "physical_deleted_at", "物理文件删除时间")
|
||||
_comment_column("upload_resources", "file_delete_status", "文件删除状态:active待删/deleting删除中/deleted已删除/error失败")
|
||||
_comment_column("upload_resources", "file_delete_error", "文件删除失败信息")
|
||||
_comment_column("upload_resources", "created_at", "创建时间")
|
||||
_comment_column("upload_resources", "updated_at", "更新时间")
|
||||
_comment_column("upload_resources", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# image_engines 表
|
||||
# ============================================================
|
||||
_comment_table("image_engines", "图片生成引擎配置表")
|
||||
_comment_column("image_engines", "id", "主键ID")
|
||||
_comment_column("image_engines", "name", "引擎显示名称")
|
||||
_comment_column("image_engines", "provider", "供应商:ark/其他")
|
||||
_comment_column("image_engines", "api_base", "API基础地址")
|
||||
_comment_column("image_engines", "api_key", "API密钥")
|
||||
_comment_column("image_engines", "model_name", "模型名")
|
||||
_comment_column("image_engines", "supported_models", "支持的模型列表JSON")
|
||||
_comment_column("image_engines", "supported_sizes", "支持尺寸JSON:{分辨率:{比例:像素}}")
|
||||
_comment_column("image_engines", "default_size", "默认分辨率档位")
|
||||
_comment_column("image_engines", "max_image_count", "允许生成图片数量上限")
|
||||
_comment_column("image_engines", "multi_generation_enabled", "是否允许多份生成")
|
||||
_comment_column("image_engines", "max_generation_count", "多份生成最大份数")
|
||||
_comment_column("image_engines", "multi_image_max_images", "组图接口参考图+生成图数量上限")
|
||||
_comment_column("image_engines", "max_reference_image_count", "最多参考图片张数")
|
||||
_comment_column("image_engines", "output_format", "输出格式,空表示使用默认")
|
||||
_comment_column("image_engines", "generate_url", "生成接口URL,留空使用SDK默认")
|
||||
_comment_column("image_engines", "is_active", "是否启用")
|
||||
_comment_column("image_engines", "priority", "排序优先级,越大越优先")
|
||||
_comment_column("image_engines", "created_at", "创建时间")
|
||||
_comment_column("image_engines", "updated_at", "更新时间")
|
||||
_comment_column("image_engines", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# video_engines 表
|
||||
# ============================================================
|
||||
_comment_table("video_engines", "视频生成引擎配置表")
|
||||
_comment_column("video_engines", "id", "主键ID")
|
||||
_comment_column("video_engines", "name", "引擎显示名称")
|
||||
_comment_column("video_engines", "provider", "供应商:ark/其他")
|
||||
_comment_column("video_engines", "api_base", "API基础地址")
|
||||
_comment_column("video_engines", "api_key", "API密钥")
|
||||
_comment_column("video_engines", "model_name", "模型名")
|
||||
_comment_column("video_engines", "supported_ratios", "支持比例JSON数组")
|
||||
_comment_column("video_engines", "supported_resolutions", "支持分辨率JSON数组")
|
||||
_comment_column("video_engines", "supported_durations", "支持时长JSON数组")
|
||||
_comment_column("video_engines", "max_duration", "最大时长秒数")
|
||||
_comment_column("video_engines", "max_image_count", "最多参考图片张数,0表示不支持")
|
||||
_comment_column("video_engines", "max_video_count", "最多参考视频段数,0表示不支持")
|
||||
_comment_column("video_engines", "max_audio_count", "最多参考音频段数,0表示不支持")
|
||||
_comment_column("video_engines", "multi_generation_enabled", "是否允许多份生成")
|
||||
_comment_column("video_engines", "max_generation_count", "多份生成最大份数")
|
||||
_comment_column("video_engines", "supports_first_last_frame", "是否支持首尾帧参考")
|
||||
_comment_column("video_engines", "supports_universal_reference", "是否支持通用参考素材")
|
||||
_comment_column("video_engines", "generate_url", "生成接口URL")
|
||||
_comment_column("video_engines", "query_url", "查询接口URL")
|
||||
_comment_column("video_engines", "is_active", "是否启用")
|
||||
_comment_column("video_engines", "priority", "排序优先级")
|
||||
_comment_column("video_engines", "created_at", "创建时间")
|
||||
_comment_column("video_engines", "updated_at", "更新时间")
|
||||
_comment_column("video_engines", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# model_configs 表
|
||||
# ============================================================
|
||||
_comment_table("model_configs", "文本模型配置表(提示词优化等文本模型)")
|
||||
_comment_column("model_configs", "id", "主键ID")
|
||||
_comment_column("model_configs", "name", "模型显示名称")
|
||||
_comment_column("model_configs", "provider", "供应商")
|
||||
_comment_column("model_configs", "api_base", "API基础地址")
|
||||
_comment_column("model_configs", "api_key", "API密钥")
|
||||
_comment_column("model_configs", "model_name", "模型名")
|
||||
_comment_column("model_configs", "weight", "权重,权重选择时使用")
|
||||
_comment_column("model_configs", "max_tokens", "最大输出Token数")
|
||||
_comment_column("model_configs", "temperature", "采样温度")
|
||||
_comment_column("model_configs", "is_active", "是否启用")
|
||||
_comment_column("model_configs", "priority", "排序优先级")
|
||||
_comment_column("model_configs", "created_at", "创建时间")
|
||||
_comment_column("model_configs", "updated_at", "更新时间")
|
||||
_comment_column("model_configs", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# system_configs 表
|
||||
# ============================================================
|
||||
_comment_table("system_configs", "系统配置表")
|
||||
_comment_column("system_configs", "id", "主键ID")
|
||||
_comment_column("system_configs", "key", "配置键名,唯一")
|
||||
_comment_column("system_configs", "value", "配置值")
|
||||
_comment_column("system_configs", "description", "配置说明")
|
||||
_comment_column("system_configs", "created_at", "创建时间")
|
||||
_comment_column("system_configs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# operation_logs 表
|
||||
# ============================================================
|
||||
_comment_table("operation_logs", "操作日志表")
|
||||
_comment_column("operation_logs", "id", "主键ID")
|
||||
_comment_column("operation_logs", "user_id", "操作用户ID")
|
||||
_comment_column("operation_logs", "username", "操作用户名")
|
||||
_comment_column("operation_logs", "action", "操作动作:CREATE/UPDATE/DELETE等")
|
||||
_comment_column("operation_logs", "method", "HTTP方法:GET/POST/PUT/DELETE")
|
||||
_comment_column("operation_logs", "path", "请求路径")
|
||||
_comment_column("operation_logs", "detail", "操作详情JSON")
|
||||
_comment_column("operation_logs", "ip", "客户端IP")
|
||||
_comment_column("operation_logs", "created_at", "创建时间")
|
||||
_comment_column("operation_logs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# notifications 表
|
||||
# ============================================================
|
||||
_comment_table("notifications", "通知消息表")
|
||||
_comment_column("notifications", "id", "主键ID")
|
||||
_comment_column("notifications", "user_id", "接收用户ID,NULL表示全体广播")
|
||||
_comment_column("notifications", "title", "通知标题")
|
||||
_comment_column("notifications", "content", "通知内容")
|
||||
_comment_column("notifications", "type", "通知类型:system系统公告/billing账单通知等")
|
||||
_comment_column("notifications", "is_read", "是否已读")
|
||||
_comment_column("notifications", "related_id", "关联业务ID")
|
||||
_comment_column("notifications", "created_at", "创建时间")
|
||||
_comment_column("notifications", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# recharge_packages 表
|
||||
# ============================================================
|
||||
_comment_table("recharge_packages", "积分充值套餐表")
|
||||
_comment_column("recharge_packages", "id", "主键ID")
|
||||
_comment_column("recharge_packages", "name", "套餐名称")
|
||||
_comment_column("recharge_packages", "credits", "套餐包含积分")
|
||||
_comment_column("recharge_packages", "price", "套餐价格(元)")
|
||||
_comment_column("recharge_packages", "bonus_credits", "赠送积分")
|
||||
_comment_column("recharge_packages", "description", "套餐描述")
|
||||
_comment_column("recharge_packages", "package_type", "套餐类型:normal普通/gift赠送首充等")
|
||||
_comment_column("recharge_packages", "is_gift", "是否赠送套餐")
|
||||
_comment_column("recharge_packages", "is_active", "是否启用")
|
||||
_comment_column("recharge_packages", "sort_order", "排序值,越小越靠前")
|
||||
_comment_column("recharge_packages", "created_at", "创建时间")
|
||||
_comment_column("recharge_packages", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# payment_orders 表
|
||||
# ============================================================
|
||||
_comment_table("payment_orders", "支付订单表")
|
||||
_comment_column("payment_orders", "id", "主键ID")
|
||||
_comment_column("payment_orders", "user_id", "下单用户ID")
|
||||
_comment_column("payment_orders", "order_no", "订单号,唯一")
|
||||
_comment_column("payment_orders", "amount", "支付金额(元)")
|
||||
_comment_column("payment_orders", "credits", "获得积分总数(含赠送)")
|
||||
_comment_column("payment_orders", "payment_method", "支付方式:wxpay/alipay等")
|
||||
_comment_column("payment_orders", "status", "订单状态:pending待支付/paid已支付/refunded已退款/failed失败")
|
||||
_comment_column("payment_orders", "paid_at", "支付成功时间")
|
||||
_comment_column("payment_orders", "trade_no", "第三方支付流水号")
|
||||
_comment_column("payment_orders", "refund_trade_no", "退款流水号")
|
||||
_comment_column("payment_orders", "refunded_at", "退款完成时间")
|
||||
_comment_column("payment_orders", "refund_amount", "退款金额")
|
||||
_comment_column("payment_orders", "created_at", "创建时间")
|
||||
_comment_column("payment_orders", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# video_upscale_tasks 表
|
||||
# ============================================================
|
||||
_comment_table("video_upscale_tasks", "视频超分任务表")
|
||||
_comment_column("video_upscale_tasks", "id", "主键ID")
|
||||
_comment_column("video_upscale_tasks", "chat_generation_task_id", "关联AI创作任务ID,与generation_record_id二选一")
|
||||
_comment_column("video_upscale_tasks", "generation_record_id", "关联项目生成记录ID,与chat_generation_task_id二选一")
|
||||
_comment_column("video_upscale_tasks", "api_generation_task_id", "关联API生成任务ID")
|
||||
_comment_column("video_upscale_tasks", "status", "任务状态:pending/processing/success/failed")
|
||||
_comment_column("video_upscale_tasks", "stage", "阶段:upscale_queued/upscale_processing等")
|
||||
_comment_column("video_upscale_tasks", "processor_key", "处理节点标识")
|
||||
_comment_column("video_upscale_tasks", "attempt_count", "执行尝试次数")
|
||||
_comment_column("video_upscale_tasks", "failure_count", "失败次数")
|
||||
_comment_column("video_upscale_tasks", "manual_retry_count", "手动重试次数")
|
||||
_comment_column("video_upscale_tasks", "next_retry_at", "下次重试时间")
|
||||
_comment_column("video_upscale_tasks", "last_error", "最后错误信息")
|
||||
_comment_column("video_upscale_tasks", "source_local_path", "源视频本地路径")
|
||||
_comment_column("video_upscale_tasks", "source_file_size_bytes", "源文件大小(字节)")
|
||||
_comment_column("video_upscale_tasks", "source_width", "源视频宽度")
|
||||
_comment_column("video_upscale_tasks", "source_height", "源视频高度")
|
||||
_comment_column("video_upscale_tasks", "source_duration_seconds", "源视频时长秒数")
|
||||
_comment_column("video_upscale_tasks", "source_deleted_at", "源文件删除时间")
|
||||
_comment_column("video_upscale_tasks", "source_delete_error", "源文件删除错误")
|
||||
_comment_column("video_upscale_tasks", "source_remote_url", "源文件远程URL")
|
||||
_comment_column("video_upscale_tasks", "source_remote_url_signed_at", "远程URL签名时间")
|
||||
_comment_column("video_upscale_tasks", "source_remote_url_expires_at", "远程URL过期时间")
|
||||
_comment_column("video_upscale_tasks", "source_remote_url_last_probe_at", "远程URL最后探测时间")
|
||||
_comment_column("video_upscale_tasks", "source_remote_url_probe_status", "远程URL探测状态")
|
||||
_comment_column("video_upscale_tasks", "input_source_type", "输入源类型:local/remote")
|
||||
_comment_column("video_upscale_tasks", "input_source_fallback_count", "输入源回退次数")
|
||||
_comment_column("video_upscale_tasks", "target_width", "目标宽度像素")
|
||||
_comment_column("video_upscale_tasks", "target_height", "目标高度像素")
|
||||
_comment_column("video_upscale_tasks", "effective_target_width", "实际生效目标宽度")
|
||||
_comment_column("video_upscale_tasks", "effective_target_height", "实际生效目标高度")
|
||||
_comment_column("video_upscale_tasks", "provider_task_id", "供应商超分任务ID")
|
||||
_comment_column("video_upscale_tasks", "provider_request_json", "供应商请求JSON")
|
||||
_comment_column("video_upscale_tasks", "provider_response_json", "供应商响应JSON")
|
||||
_comment_column("video_upscale_tasks", "provider_output_url", "供应商输出URL")
|
||||
_comment_column("video_upscale_tasks", "provider_output_url_expires_at", "供应商输出URL过期")
|
||||
_comment_column("video_upscale_tasks", "provider_submitted_at", "提交供应商时间")
|
||||
_comment_column("video_upscale_tasks", "final_local_path", "最终本地文件路径")
|
||||
_comment_column("video_upscale_tasks", "final_resource_url", "最终资源访问URL")
|
||||
_comment_column("video_upscale_tasks", "final_file_size_bytes", "最终文件大小(字节)")
|
||||
_comment_column("video_upscale_tasks", "celery_task_id", "Celery任务ID")
|
||||
_comment_column("video_upscale_tasks", "lease_token", "分布式租约token")
|
||||
_comment_column("video_upscale_tasks", "lease_until", "租约过期时间")
|
||||
_comment_column("video_upscale_tasks", "started_at", "开始处理时间")
|
||||
_comment_column("video_upscale_tasks", "completed_at", "完成时间")
|
||||
_comment_column("video_upscale_tasks", "failed_at", "失败时间")
|
||||
_comment_column("video_upscale_tasks", "created_at", "创建时间")
|
||||
_comment_column("video_upscale_tasks", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# shot_replicate_task_sets 表
|
||||
# ============================================================
|
||||
_comment_table("shot_replicate_task_sets", "拆镜复刻总任务集")
|
||||
_comment_column("shot_replicate_task_sets", "id", "主键ID")
|
||||
_comment_column("shot_replicate_task_sets", "user_id", "所属用户ID")
|
||||
_comment_column("shot_replicate_task_sets", "title", "任务集标题")
|
||||
_comment_column("shot_replicate_task_sets", "video_url", "上传视频访问URL")
|
||||
_comment_column("shot_replicate_task_sets", "video_path", "上传视频存储路径")
|
||||
_comment_column("shot_replicate_task_sets", "video_duration_seconds", "上传视频总时长秒数")
|
||||
_comment_column("shot_replicate_task_sets", "status", "总任务状态:pending_analysis/analyzing/analysis_done等")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_status", "AI分析状态:pending/processing/success/failed")
|
||||
_comment_column("shot_replicate_task_sets", "split_status", "切片状态:none/slicing/sliced")
|
||||
_comment_column("shot_replicate_task_sets", "original_video_content", "原视频内容描述")
|
||||
_comment_column("shot_replicate_task_sets", "original_video_category", "原视频行业分类")
|
||||
_comment_column("shot_replicate_task_sets", "original_video_audience", "原视频目标受众")
|
||||
_comment_column("shot_replicate_task_sets", "ai_suggestion_json", "AI复刻建议JSON")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_raw_json", "AI分析原始JSON")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_result_json", "AI分析结果JSON")
|
||||
_comment_column("shot_replicate_task_sets", "segment_count", "总拆镜头数")
|
||||
_comment_column("shot_replicate_task_sets", "completed_segment_count", "已完成镜头数")
|
||||
_comment_column("shot_replicate_task_sets", "failed_segment_count", "失败镜头数")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_attempt_no", "AI分析尝试次数")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_claim_token", "AI分析租约token")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_started_at", "AI分析开始时间")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_lease_until", "AI分析租约过期")
|
||||
_comment_column("shot_replicate_task_sets", "analysis_error_message", "AI分析错误信息")
|
||||
_comment_column("shot_replicate_task_sets", "split_error_message", "切片错误信息")
|
||||
_comment_column("shot_replicate_task_sets", "idempotency_key", "幂等键")
|
||||
_comment_column("shot_replicate_task_sets", "created_at", "创建时间")
|
||||
_comment_column("shot_replicate_task_sets", "updated_at", "更新时间")
|
||||
_comment_column("shot_replicate_task_sets", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# teams 表(已经有部分comment,补齐未加的)
|
||||
# ============================================================
|
||||
_comment_table("teams", "团队表")
|
||||
_comment_column("teams", "id", "主键ID")
|
||||
_comment_column("teams", "name", "团队名称")
|
||||
_comment_column("teams", "code", "团队编码")
|
||||
_comment_column("teams", "description", "团队备注")
|
||||
_comment_column("teams", "status", "团队状态:active启用,disabled禁用")
|
||||
_comment_column("teams", "sort_order", "排序值,越小越靠前")
|
||||
_comment_column("teams", "manager_id", "团队管理人ID")
|
||||
_comment_column("teams", "created_at", "创建时间")
|
||||
_comment_column("teams", "updated_at", "更新时间")
|
||||
_comment_column("teams", "deleted_at", "软删除时间")
|
||||
|
||||
# ============================================================
|
||||
# user_resource_capacity_configs 表(已部分有comment)
|
||||
# ============================================================
|
||||
_comment_table("user_resource_capacity_configs", "用户个人容量配置表")
|
||||
_comment_column("user_resource_capacity_configs", "id", "主键ID")
|
||||
_comment_column("user_resource_capacity_configs", "user_id", "用户ID")
|
||||
_comment_column("user_resource_capacity_configs", "enabled", "是否启用该用户个人容量限制")
|
||||
_comment_column("user_resource_capacity_configs", "limit_value", "容量数值,最小1,最多3位小数")
|
||||
_comment_column("user_resource_capacity_configs", "limit_unit", "容量单位:MB/GB/TB")
|
||||
_comment_column("user_resource_capacity_configs", "limit_bytes", "换算后的容量字节数")
|
||||
_comment_column("user_resource_capacity_configs", "created_at", "创建时间")
|
||||
_comment_column("user_resource_capacity_configs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# resources_material 表(已部分有comment)
|
||||
# ============================================================
|
||||
_comment_table("resources_material", "资源素材对接表(第三方平台素材同步)")
|
||||
_comment_column("resources_material", "id", "主键")
|
||||
_comment_column("resources_material", "oauth_id", "授权表user_oauth自增id")
|
||||
_comment_column("resources_material", "advertiser_id", "广告主id")
|
||||
_comment_column("resources_material", "target_table", "资源表名称")
|
||||
_comment_column("resources_material", "target_id", "资源表id")
|
||||
_comment_column("resources_material", "material_id", "素材id")
|
||||
_comment_column("resources_material", "upload_id", "上传资源平台id,图片id,视频id")
|
||||
_comment_column("resources_material", "resource_type", "资源类型,image或者video")
|
||||
_comment_column("resources_material", "user_id", "用户登录id")
|
||||
_comment_column("resources_material", "task_id", "前测任务id")
|
||||
_comment_column("resources_material", "note", "前测失败备注或者其他备注")
|
||||
_comment_column("resources_material", "status", "前测状态(FAILED/PENDING/SUCCESS)")
|
||||
_comment_column("resources_material", "pre_result", "前测结果,JSON数组对象")
|
||||
_comment_column("resources_material", "pre_test_template_id", "前测模板id")
|
||||
_comment_column("resources_material", "created_at", "创建时间")
|
||||
_comment_column("resources_material", "updated_at", "更新时间")
|
||||
_comment_column("resources_material", "deleted_at", "软删除时间")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# 注释回滚时选择清空所有注释即可,不影响功能
|
||||
op.execute("""
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT table_name, column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name IN (
|
||||
'users', 'projects', 'credit_ratios', 'credit_records',
|
||||
'chat_generation_tasks', 'generation_records',
|
||||
'generated_resources', 'upload_resources',
|
||||
'image_engines', 'video_engines', 'model_configs',
|
||||
'system_configs', 'operation_logs', 'notifications',
|
||||
'recharge_packages', 'payment_orders',
|
||||
'video_upscale_tasks', 'shot_replicate_task_sets',
|
||||
'teams', 'user_resource_capacity_configs',
|
||||
'resources_material'
|
||||
)
|
||||
LOOP
|
||||
EXECUTE format('COMMENT ON COLUMN %I.%I IS NULL', r.table_name, r.column_name);
|
||||
END LOOP;
|
||||
END $$;
|
||||
""")
|
||||
# 清空表注释
|
||||
for t in [
|
||||
"users", "projects", "credit_ratios", "credit_records",
|
||||
"chat_generation_tasks", "generation_records",
|
||||
"generated_resources", "upload_resources",
|
||||
"image_engines", "video_engines", "model_configs",
|
||||
"system_configs", "operation_logs", "notifications",
|
||||
"recharge_packages", "payment_orders",
|
||||
"video_upscale_tasks", "shot_replicate_task_sets",
|
||||
"teams", "user_resource_capacity_configs",
|
||||
"resources_material",
|
||||
]:
|
||||
op.execute(f"COMMENT ON TABLE {t} IS NULL")
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
"""2026080401_add_vp_v3_virtual_portrait_tables_and_quota
|
||||
|
||||
Revision ID: 2026080401
|
||||
Revises: 2026073101
|
||||
Create Date: 2026-08-04 00:00:00.000000
|
||||
|
||||
API V3 虚拟素材库中转表 + 密钥配额表:
|
||||
1. vp_v3_api_key_quotas: 每个 API Key 的虚拟素材配额(项目数/素材数/存储 MB)
|
||||
2. vp_v3_projects: V3 虚拟素材项目(=火山一个 AssetGroup)
|
||||
3. vp_v3_assets: V3 虚拟素材(图片/视频)
|
||||
|
||||
备注:
|
||||
* 数据与前台用户私域素材库(private_portrait_* 表)完全隔离
|
||||
* 归属按 api_keys.id(V3 调用方)而非 users.id
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision: str = '2026080401'
|
||||
down_revision: Union[str, None] = '2026073101'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ==============================================================
|
||||
# 1. vp_v3_api_key_quotas:API Key 虚拟素材配额
|
||||
# ==============================================================
|
||||
op.create_table(
|
||||
'vp_v3_api_key_quotas',
|
||||
sa.Column('id', sa.String(length=32), nullable=False, comment='主键ID'),
|
||||
sa.Column('api_key_id', sa.String(length=32), nullable=False,
|
||||
comment='所属 API Key,唯一:一个 API Key 只有一份虚拟素材配额'),
|
||||
# 配额上限(默认 0=不可用)
|
||||
sa.Column('project_limit', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='虚拟项目上限,默认 0 不可创建'),
|
||||
sa.Column('asset_limit', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='虚拟素材总数上限(图片+视频),默认 0 不可上传'),
|
||||
sa.Column('storage_mb_limit', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='上传存储上限 MB,默认 0 不可上传文件'),
|
||||
# 已使用量(冗余,每次增删同步,和 COUNT 不一致时以 COUNT 为准)
|
||||
sa.Column('project_used', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='已创建项目数(未删除)'),
|
||||
sa.Column('asset_used', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='已上传素材数(未删除,图片+视频)'),
|
||||
sa.Column('storage_mb_used', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='已占用存储 MB(未删除文件大小合计,1MB=1024*1024)'),
|
||||
sa.Column('remark', sa.Text(), nullable=True, comment='后台备注'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now(),
|
||||
comment='创建时间'),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
onupdate=sa.func.now(),
|
||||
comment='最后更新时间'),
|
||||
sa.ForeignKeyConstraint(['api_key_id'], ['api_keys.id'], ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
)
|
||||
op.create_unique_constraint('uq_vp_v3_api_key_quotas_key_id', 'vp_v3_api_key_quotas', ['api_key_id'])
|
||||
op.create_index('idx_vp_v3_api_key_quotas_api_key_id', 'vp_v3_api_key_quotas', ['api_key_id'])
|
||||
|
||||
# ==============================================================
|
||||
# 2. vp_v3_projects:V3 虚拟素材项目
|
||||
# ==============================================================
|
||||
op.create_table(
|
||||
'vp_v3_projects',
|
||||
sa.Column('id', sa.String(length=32), nullable=False, comment='项目ID'),
|
||||
sa.Column('api_key_id', sa.String(length=32), nullable=False,
|
||||
comment='所属 API Key(V3 调用方)'),
|
||||
sa.Column('name', sa.String(length=128), nullable=False, comment='项目展示名称'),
|
||||
sa.Column('name_slug', sa.String(length=128), nullable=False, comment='名称安全 slug(构建远端 GroupName 用)'),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('remote_project_name', sa.String(length=256), nullable=False,
|
||||
comment='火山 ProjectName(快照)'),
|
||||
sa.Column('remote_group_id', sa.String(length=128), nullable=False,
|
||||
comment='火山 AssetGroup Id'),
|
||||
sa.Column('remote_group_name', sa.String(length=256), nullable=True,
|
||||
comment='火山 AssetGroup Name 快照'),
|
||||
sa.Column('status', sa.String(length=32), nullable=False, server_default=sa.text("'active'"),
|
||||
index=True,
|
||||
comment='项目状态:active/creating_remote_group/create_group_failed/deleting'),
|
||||
# 计数
|
||||
sa.Column('asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('active_asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('image_asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('video_asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('active_image_asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('active_video_asset_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('storage_mb_used', sa.Integer(), nullable=False, server_default=sa.text('0'),
|
||||
comment='项目占用存储 MB(未删除素材文件大小合计)'),
|
||||
sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True),
|
||||
# 远端删除状态
|
||||
sa.Column('remote_delete_status', sa.String(length=32), nullable=False, server_default=sa.text("'none'"),
|
||||
index=True, comment='远端删除状态:none/pending/processing/deleted/failed'),
|
||||
sa.Column('remote_deleted_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('remote_delete_error', sa.Text(), nullable=True),
|
||||
sa.Column('error_message', sa.Text(), nullable=True, comment='创建失败等错误信息'),
|
||||
sa.Column('raw_response_json', sa.Text(), nullable=True, comment='火山原始响应'),
|
||||
# 软删除 + 时间
|
||||
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True, comment='删除时间(NULL=未删除)'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now(),
|
||||
comment='创建时间'),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
onupdate=sa.func.now(),
|
||||
comment='最后更新时间'),
|
||||
sa.ForeignKeyConstraint(['api_key_id'], ['api_keys.id'], ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
)
|
||||
op.create_index('idx_vp_v3_projects_key_status_created', 'vp_v3_projects',
|
||||
['api_key_id', 'status', 'created_at'])
|
||||
op.create_index('idx_vp_v3_projects_remote_project_name', 'vp_v3_projects', ['remote_project_name'])
|
||||
op.create_index('idx_vp_v3_projects_remote_group_id', 'vp_v3_projects', ['remote_group_id'])
|
||||
op.execute(
|
||||
"CREATE INDEX idx_vp_v3_projects_key_deleted ON vp_v3_projects (api_key_id, deleted_at)"
|
||||
" WHERE deleted_at IS NULL;"
|
||||
)
|
||||
|
||||
# ==============================================================
|
||||
# 3. vp_v3_assets:V3 虚拟素材
|
||||
# ==============================================================
|
||||
op.create_table(
|
||||
'vp_v3_assets',
|
||||
sa.Column('id', sa.String(length=32), nullable=False, comment='素材ID'),
|
||||
sa.Column('api_key_id', sa.String(length=32), nullable=False,
|
||||
comment='所属 API Key(V3 调用方)'),
|
||||
sa.Column('project_id', sa.String(length=32), nullable=False, comment='所属项目ID'),
|
||||
sa.Column('remote_project_name', sa.String(length=256), nullable=False,
|
||||
comment='火山 ProjectName'),
|
||||
sa.Column('remote_group_id', sa.String(length=128), nullable=False,
|
||||
comment='火山 AssetGroup Id'),
|
||||
sa.Column('remote_asset_id', sa.String(length=128), nullable=True, comment='火山素材 Id'),
|
||||
sa.Column('asset_type', sa.String(length=16), nullable=False, server_default=sa.text("'Image'"),
|
||||
comment='素材类型:Image=图片 / Video=视频', index=True),
|
||||
sa.Column('name', sa.String(length=128), nullable=True, comment='素材展示名称', index=True),
|
||||
sa.Column('source_url', sa.Text(), nullable=False, comment='本地上传后的访问 URL'),
|
||||
sa.Column('preview_url', sa.Text(), nullable=True, comment='给前端预览/显示用的 URL'),
|
||||
sa.Column('remote_url', sa.Text(), nullable=True, comment='火山返回的资源访问 URL(可能带签名)'),
|
||||
sa.Column('remote_url_expired_at', sa.DateTime(timezone=True), nullable=True,
|
||||
comment='remote_url 过期时间'),
|
||||
sa.Column('upload_resource_id', sa.String(length=32), nullable=True, index=True,
|
||||
comment='本地上传 resource_id,供容量释放用'),
|
||||
sa.Column('video_duration', sa.Float(), nullable=True, comment='视频时长,秒'),
|
||||
sa.Column('video_cover_url', sa.Text(), nullable=True, comment='视频封面预览'),
|
||||
sa.Column('file_size_bytes', sa.Integer(), nullable=True, comment='素材文件大小,字节'),
|
||||
sa.Column('mime_type', sa.String(length=128), nullable=True),
|
||||
sa.Column('status', sa.String(length=32), nullable=False, server_default=sa.text("'creating'"),
|
||||
index=True,
|
||||
comment='素材状态:creating/审核中 active/可用 failed/失败 deleting/删除中'),
|
||||
sa.Column('moderation_json', sa.Text(), nullable=True, comment='火山审核结果 JSON'),
|
||||
sa.Column('error_message', sa.Text(), nullable=True, comment='失败原因'),
|
||||
sa.Column('raw_response_json', sa.Text(), nullable=True, comment='火山原始响应 JSON'),
|
||||
sa.Column('last_poll_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('next_poll_at', sa.DateTime(timezone=True), nullable=True, index=True,
|
||||
comment='下次轮询时间(创建中状态自动轮询)'),
|
||||
sa.Column('poll_count', sa.Integer(), nullable=False, server_default=sa.text('0')),
|
||||
sa.Column('remote_delete_status', sa.String(length=32), nullable=False, server_default=sa.text("'none'"),
|
||||
index=True, comment='远端删除状态:none/pending/processing/deleted/failed'),
|
||||
sa.Column('remote_deleted_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('remote_delete_error', sa.Text(), nullable=True),
|
||||
# 软删除 + 时间
|
||||
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True, comment='删除时间(NULL=未删除)'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now(),
|
||||
comment='创建时间'),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=False,
|
||||
server_default=sa.func.now(),
|
||||
onupdate=sa.func.now(),
|
||||
comment='最后更新时间'),
|
||||
sa.ForeignKeyConstraint(['api_key_id'], ['api_keys.id'], ondelete='CASCADE'),
|
||||
sa.ForeignKeyConstraint(['project_id'], ['vp_v3_projects.id'], ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
)
|
||||
op.create_unique_constraint('uq_vp_v3_assets_remote_asset_id', 'vp_v3_assets', ['remote_asset_id'])
|
||||
op.create_index('idx_vp_v3_assets_key_status_created', 'vp_v3_assets',
|
||||
['api_key_id', 'status', 'created_at'])
|
||||
op.create_index('idx_vp_v3_assets_project_status_created', 'vp_v3_assets',
|
||||
['project_id', 'status', 'created_at'])
|
||||
op.create_index('idx_vp_v3_assets_asset_type', 'vp_v3_assets', ['asset_type'])
|
||||
op.create_index('idx_vp_v3_assets_remote_delete_status', 'vp_v3_assets', ['remote_delete_status'])
|
||||
op.execute(
|
||||
"CREATE INDEX idx_vp_v3_assets_next_poll_status ON vp_v3_assets (next_poll_at, status)"
|
||||
" WHERE deleted_at IS NULL AND next_poll_at IS NOT NULL;"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table('vp_v3_assets')
|
||||
op.drop_table('vp_v3_projects')
|
||||
op.drop_index('idx_vp_v3_api_key_quotas_api_key_id', table_name='vp_v3_api_key_quotas')
|
||||
op.drop_constraint('uq_vp_v3_api_key_quotas_key_id', 'vp_v3_api_key_quotas', type_='unique')
|
||||
op.drop_table('vp_v3_api_key_quotas')
|
||||
@@ -0,0 +1,984 @@
|
||||
"""2026080601_add_missing_table_and_column_comments
|
||||
|
||||
Revision ID: 2026080601
|
||||
Revises: 2026080401
|
||||
Create Date: 2026-08-06 00:00:00.000000
|
||||
|
||||
给前端迁移遗漏的 models 表添加表注释和字段注释。
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
revision: str = '2026080601'
|
||||
down_revision: Union[str, None] = '2026080401'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def _comment_table(table_name: str, comment: str) -> None:
|
||||
op.execute(f"COMMENT ON TABLE {table_name} IS '{comment}'")
|
||||
|
||||
|
||||
def _comment_column(table_name: str, column_name: str, comment: str) -> None:
|
||||
escaped = comment.replace("'", "''")
|
||||
op.execute(f"COMMENT ON COLUMN {table_name}.{column_name} IS '{escaped}'")
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ============================================================
|
||||
# notification_reads 表
|
||||
# ============================================================
|
||||
_comment_table("notification_reads", "通知已读记录表")
|
||||
_comment_column("notification_reads", "id", "主键ID")
|
||||
_comment_column("notification_reads", "notification_id", "通知ID")
|
||||
_comment_column("notification_reads", "user_id", "已读用户ID")
|
||||
_comment_column("notification_reads", "created_at", "创建时间")
|
||||
_comment_column("notification_reads", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# menu_configs 表
|
||||
# ============================================================
|
||||
_comment_table("menu_configs", "菜单配置表")
|
||||
_comment_column("menu_configs", "id", "主键ID")
|
||||
_comment_column("menu_configs", "label", "菜单显示名称")
|
||||
_comment_column("menu_configs", "path", "菜单路由路径")
|
||||
_comment_column("menu_configs", "icon", "菜单图标名称")
|
||||
_comment_column("menu_configs", "sort_order", "排序值,越小越靠前")
|
||||
_comment_column("menu_configs", "is_active", "是否启用")
|
||||
_comment_column("menu_configs", "parent_id", "父菜单ID")
|
||||
_comment_column("menu_configs", "menu_type", "菜单类型:page页面/directory目录/link链接")
|
||||
_comment_column("menu_configs", "menu_target", "菜单目标:frontend前台/admin后台")
|
||||
_comment_column("menu_configs", "is_default", "是否默认菜单,新用户自动分配")
|
||||
_comment_column("menu_configs", "created_at", "创建时间")
|
||||
_comment_column("menu_configs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# team_join_requests 表
|
||||
# ============================================================
|
||||
_comment_table("team_join_requests", "团队加入申请记录表")
|
||||
_comment_column("team_join_requests", "id", "主键ID")
|
||||
_comment_column("team_join_requests", "team_id", "目标团队ID")
|
||||
_comment_column("team_join_requests", "user_id", "申请人用户ID")
|
||||
_comment_column("team_join_requests", "invitation_id", "关联邀请ID(通过邀请链接申请时记录)")
|
||||
_comment_column("team_join_requests", "status", "申请状态:pending待处理/approved已通过/rejected已拒绝")
|
||||
_comment_column("team_join_requests", "note", "申请备注")
|
||||
_comment_column("team_join_requests", "handled_by", "处理人用户ID")
|
||||
_comment_column("team_join_requests", "created_at", "创建时间")
|
||||
_comment_column("team_join_requests", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# team_invitations 表
|
||||
# ============================================================
|
||||
_comment_table("team_invitations", "团队邀请记录表")
|
||||
_comment_column("team_invitations", "id", "主键ID")
|
||||
_comment_column("team_invitations", "team_id", "所属团队ID")
|
||||
_comment_column("team_invitations", "code", "邀请码,唯一")
|
||||
_comment_column("team_invitations", "created_by", "创建人用户ID")
|
||||
_comment_column("team_invitations", "status", "邀请状态:active启用/disabled禁用")
|
||||
_comment_column("team_invitations", "max_uses", "最大使用次数,NULL表示不限")
|
||||
_comment_column("team_invitations", "use_count", "已使用次数")
|
||||
_comment_column("team_invitations", "expires_at", "过期时间,NULL表示永不过期")
|
||||
_comment_column("team_invitations", "created_at", "创建时间")
|
||||
_comment_column("team_invitations", "updated_at", "更新时间")
|
||||
_comment_column("team_invitations", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# contact_requests 表
|
||||
# ============================================================
|
||||
_comment_table("contact_requests", "用户联系/咨询申请表")
|
||||
_comment_column("contact_requests", "id", "主键ID")
|
||||
_comment_column("contact_requests", "user_id", "提交用户ID")
|
||||
_comment_column("contact_requests", "phone", "联系电话")
|
||||
_comment_column("contact_requests", "company_name", "公司名称")
|
||||
_comment_column("contact_requests", "industry", "所属行业")
|
||||
_comment_column("contact_requests", "name", "联系人姓名")
|
||||
_comment_column("contact_requests", "message", "留言内容")
|
||||
_comment_column("contact_requests", "is_handled", "是否已处理")
|
||||
_comment_column("contact_requests", "submit_date", "提交日期(YYYY-MM-DD),用于每日限1次控制")
|
||||
_comment_column("contact_requests", "created_at", "创建时间")
|
||||
_comment_column("contact_requests", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# token_usage 表
|
||||
# ============================================================
|
||||
_comment_table("token_usage", "Token消耗记录表")
|
||||
_comment_column("token_usage", "id", "主键ID")
|
||||
_comment_column("token_usage", "model_config_id", "模型配置ID")
|
||||
_comment_column("token_usage", "user_id", "所属用户ID")
|
||||
_comment_column("token_usage", "input_tokens", "输入Token数")
|
||||
_comment_column("token_usage", "output_tokens", "输出Token数")
|
||||
_comment_column("token_usage", "total_tokens", "总Token数")
|
||||
_comment_column("token_usage", "owner_type", "归属类型:chat_generation_task/module_generation_step等")
|
||||
_comment_column("token_usage", "owner_id", "归属记录ID")
|
||||
_comment_column("token_usage", "biz_key", "业务幂等键")
|
||||
_comment_column("token_usage", "source_module", "来源模块")
|
||||
_comment_column("token_usage", "source_step_code", "来源步骤编码")
|
||||
_comment_column("token_usage", "created_at", "创建时间")
|
||||
_comment_column("token_usage", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# industry_configs 表
|
||||
# ============================================================
|
||||
_comment_table("industry_configs", "行业配置表")
|
||||
_comment_column("industry_configs", "id", "主键ID")
|
||||
_comment_column("industry_configs", "key", "行业唯一标识键")
|
||||
_comment_column("industry_configs", "label", "行业显示名称")
|
||||
_comment_column("industry_configs", "icon", "图标名称")
|
||||
_comment_column("industry_configs", "description", "行业描述")
|
||||
_comment_column("industry_configs", "skills", "行业技能列表JSON数组")
|
||||
_comment_column("industry_configs", "is_active", "是否启用")
|
||||
_comment_column("industry_configs", "sort_order", "排序值,越小越靠前")
|
||||
_comment_column("industry_configs", "created_at", "创建时间")
|
||||
_comment_column("industry_configs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# chat_generation_task_events 表
|
||||
# ============================================================
|
||||
_comment_table("chat_generation_task_events", "AI创作任务事件日志表(追加写入)")
|
||||
_comment_column("chat_generation_task_events", "id", "主键ID")
|
||||
_comment_column("chat_generation_task_events", "owner_type", "归属类型:chat_generation_task/generation_record")
|
||||
_comment_column("chat_generation_task_events", "task_id", "关联AI创作任务ID")
|
||||
_comment_column("chat_generation_task_events", "generation_record_id", "关联项目生成记录ID")
|
||||
_comment_column("chat_generation_task_events", "generation_attempt_no", "生成尝试次数")
|
||||
_comment_column("chat_generation_task_events", "generation_mode", "生成模式")
|
||||
_comment_column("chat_generation_task_events", "event_type", "事件类型")
|
||||
_comment_column("chat_generation_task_events", "from_status", "变更前状态")
|
||||
_comment_column("chat_generation_task_events", "to_status", "变更后状态")
|
||||
_comment_column("chat_generation_task_events", "from_stage", "变更前阶段")
|
||||
_comment_column("chat_generation_task_events", "to_stage", "变更后阶段")
|
||||
_comment_column("chat_generation_task_events", "message", "事件描述信息")
|
||||
_comment_column("chat_generation_task_events", "detail_json", "事件详情JSON")
|
||||
_comment_column("chat_generation_task_events", "created_at", "创建时间")
|
||||
|
||||
# ============================================================
|
||||
# chat_provider_call_logs 表
|
||||
# ============================================================
|
||||
_comment_table("chat_provider_call_logs", "供应商调用审计日志表")
|
||||
_comment_column("chat_provider_call_logs", "id", "主键ID")
|
||||
_comment_column("chat_provider_call_logs", "owner_type", "归属类型:chat_generation_task/generation_record")
|
||||
_comment_column("chat_provider_call_logs", "task_id", "关联AI创作任务ID")
|
||||
_comment_column("chat_provider_call_logs", "generation_record_id", "关联项目生成记录ID")
|
||||
_comment_column("chat_provider_call_logs", "generation_attempt_no", "生成尝试次数")
|
||||
_comment_column("chat_provider_call_logs", "generation_mode", "生成模式")
|
||||
_comment_column("chat_provider_call_logs", "provider", "供应商:ark/seedance等")
|
||||
_comment_column("chat_provider_call_logs", "api_type", "API类型:image_generate/video_create等")
|
||||
_comment_column("chat_provider_call_logs", "model", "模型名称")
|
||||
_comment_column("chat_provider_call_logs", "engine_id", "引擎ID")
|
||||
_comment_column("chat_provider_call_logs", "status", "调用状态:success/failed")
|
||||
_comment_column("chat_provider_call_logs", "latency_ms", "调用耗时(毫秒)")
|
||||
_comment_column("chat_provider_call_logs", "http_status", "HTTP状态码")
|
||||
_comment_column("chat_provider_call_logs", "provider_task_id", "供应商任务ID")
|
||||
_comment_column("chat_provider_call_logs", "request_hash", "请求内容哈希")
|
||||
_comment_column("chat_provider_call_logs", "response_hash", "响应内容哈希")
|
||||
_comment_column("chat_provider_call_logs", "request_excerpt", "请求内容摘录")
|
||||
_comment_column("chat_provider_call_logs", "response_excerpt", "响应内容摘录")
|
||||
_comment_column("chat_provider_call_logs", "prompt_tokens", "提示词Token数")
|
||||
_comment_column("chat_provider_call_logs", "completion_tokens", "补全Token数")
|
||||
_comment_column("chat_provider_call_logs", "total_tokens", "总Token数")
|
||||
_comment_column("chat_provider_call_logs", "error_code", "错误码")
|
||||
_comment_column("chat_provider_call_logs", "error_message", "错误信息")
|
||||
_comment_column("chat_provider_call_logs", "created_at", "创建时间")
|
||||
|
||||
# ============================================================
|
||||
# open_type 表
|
||||
# ============================================================
|
||||
_comment_table("open_type", "开户方式管理表")
|
||||
_comment_column("open_type", "id", "主键")
|
||||
_comment_column("open_type", "type_name", "标题名称")
|
||||
_comment_column("open_type", "open_type", "开户方式id")
|
||||
_comment_column("open_type", "description", "开户方式描述")
|
||||
_comment_column("open_type", "thumb", "缩略图")
|
||||
_comment_column("open_type", "created_at", "创建时间")
|
||||
_comment_column("open_type", "updated_at", "更新时间")
|
||||
_comment_column("open_type", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# pre_test_template 表
|
||||
# ============================================================
|
||||
_comment_table("pre_test_template", "素材前测模板表")
|
||||
_comment_column("pre_test_template", "id", "主键")
|
||||
_comment_column("pre_test_template", "name", "模板名称")
|
||||
_comment_column("pre_test_template", "user_id", "用户id")
|
||||
_comment_column("pre_test_template", "note", "模板备注")
|
||||
_comment_column("pre_test_template", "platform", "投放平台(AD/QIANCHUAN/LOCAL)")
|
||||
_comment_column("pre_test_template", "external_action", "转化目标")
|
||||
_comment_column("pre_test_template", "cpa_bid", "目标转化成本:[1, 10000]")
|
||||
_comment_column("pre_test_template", "audience_gender", "性别(ALL/MALE/FEMALE)")
|
||||
_comment_column("pre_test_template", "audience_age", "受众年龄,JSON数组")
|
||||
_comment_column("pre_test_template", "audience_region", "受众地区,JSON数组(二级行政区域code)")
|
||||
_comment_column("pre_test_template", "audience_network", "网络类型,JSON数组")
|
||||
_comment_column("pre_test_template", "cus_name", "客户主体名称")
|
||||
_comment_column("pre_test_template", "pricing_type", "出价类型(OCPC/CPA/OCPM)")
|
||||
_comment_column("pre_test_template", "cost_cap", "是否最优成本出价(仅AD支持)")
|
||||
_comment_column("pre_test_template", "target_cost", "是否稳定成本出价(仅AD支持)")
|
||||
_comment_column("pre_test_template", "nobid", "是否最大转化出价(仅AD支持)")
|
||||
_comment_column("pre_test_template", "cpc_bid", "目标点击成本:[1, 10000]")
|
||||
_comment_column("pre_test_template", "budget", "预算金额:[1, 10000]")
|
||||
_comment_column("pre_test_template", "is_default", "是否默认模板")
|
||||
_comment_column("pre_test_template", "created_at", "创建时间")
|
||||
_comment_column("pre_test_template", "updated_at", "更新时间")
|
||||
_comment_column("pre_test_template", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# material_cost 表
|
||||
# ============================================================
|
||||
_comment_table("material_cost", "素材消耗数据表(广告投放消耗统计)")
|
||||
_comment_column("material_cost", "id", "主键")
|
||||
_comment_column("material_cost", "oauth_id", "授权表user_oauth自增id")
|
||||
_comment_column("material_cost", "advertiser_id", "广告主id")
|
||||
_comment_column("material_cost", "material_id", "素材id")
|
||||
_comment_column("material_cost", "consume_date", "消耗日期")
|
||||
_comment_column("material_cost", "stat_cost", "消耗金额")
|
||||
_comment_column("material_cost", "show_cnt", "展示数")
|
||||
_comment_column("material_cost", "cpm_platform", "平均千次展现费用(元)")
|
||||
_comment_column("material_cost", "click_cnt", "点击数")
|
||||
_comment_column("material_cost", "ctr", "点击率")
|
||||
_comment_column("material_cost", "cpc_platform", "平均点击单价(元)")
|
||||
_comment_column("material_cost", "convert_cnt", "转化数")
|
||||
_comment_column("material_cost", "conversion_cost", "平均转化成本(元)")
|
||||
_comment_column("material_cost", "conversion_rate", "转化率")
|
||||
_comment_column("material_cost", "deep_convert_cnt", "深度转化数")
|
||||
_comment_column("material_cost", "deep_convert_cost", "深度转化成本(元)")
|
||||
_comment_column("material_cost", "deep_convert_rate", "深度转化率")
|
||||
_comment_column("material_cost", "active", "激活数")
|
||||
_comment_column("material_cost", "active_cost", "激活成本(元)")
|
||||
_comment_column("material_cost", "active_rate", "激活率")
|
||||
_comment_column("material_cost", "active_register", "注册数")
|
||||
_comment_column("material_cost", "active_register_cost", "注册成本(元)")
|
||||
_comment_column("material_cost", "active_register_rate", "注册率")
|
||||
_comment_column("material_cost", "attribution_next_day_open_cnt", "次留数")
|
||||
_comment_column("material_cost", "attribution_next_day_open_cost", "次留成本")
|
||||
_comment_column("material_cost", "attribution_next_day_open_rate", "次留率")
|
||||
_comment_column("material_cost", "active_pay", "首次付费数")
|
||||
_comment_column("material_cost", "active_pay_cost", "首次付费成本(元)")
|
||||
_comment_column("material_cost", "active_pay_rate", "首次付费率")
|
||||
_comment_column("material_cost", "phone", "点击电话按钮")
|
||||
_comment_column("material_cost", "form", "用户在门店落地页多线沟通提交表单的次数")
|
||||
_comment_column("material_cost", "download_start", "用户点击下载开始的次数")
|
||||
_comment_column("material_cost", "form_submit", "用户查看附加创意后,提交表单的次数")
|
||||
_comment_column("material_cost", "button", "用户点击按钮button的次数")
|
||||
_comment_column("material_cost", "view", "用户在关键页面的浏览次数")
|
||||
_comment_column("material_cost", "message", "用户点击短信咨询的次数")
|
||||
_comment_column("material_cost", "consult", "用户点击在线咨询按钮的次数")
|
||||
_comment_column("material_cost", "consult_effective", "用户在门店落地页多线沟通的在线咨询中有效咨询的次数")
|
||||
_comment_column("material_cost", "shopping", "用户购买商品的次数")
|
||||
_comment_column("material_cost", "customer_effective", "有效获客")
|
||||
_comment_column("material_cost", "attribution_game_in_app_ltv_1day", "当日付费金额")
|
||||
_comment_column("material_cost", "attribution_game_in_app_roi_1day", "当日付费ROI")
|
||||
_comment_column("material_cost", "loan_completion", "完件数")
|
||||
_comment_column("material_cost", "loan_completion_cost", "完件成本(元)")
|
||||
_comment_column("material_cost", "loan_completion_rate", "完件率")
|
||||
_comment_column("material_cost", "loan_credit", "授信数")
|
||||
_comment_column("material_cost", "loan_credit_cost", "授信成本(元)")
|
||||
_comment_column("material_cost", "loan_credit_rate", "授信率")
|
||||
_comment_column("material_cost", "in_app_order_gmv", "引流电商订单GMV")
|
||||
_comment_column("material_cost", "in_app_order_roi", "引流电商订单ROI")
|
||||
_comment_column("material_cost", "in_app_pay_gmv", "引流电商支付GMV")
|
||||
_comment_column("material_cost", "in_app_pay_roi", "引流电商支付ROI")
|
||||
_comment_column("material_cost", "total_play", "播放量")
|
||||
_comment_column("material_cost", "valid_play", "有效播放数")
|
||||
_comment_column("material_cost", "valid_play_cost", "有效播放成本(元)")
|
||||
_comment_column("material_cost", "valid_play_rate", "有效播放率")
|
||||
_comment_column("material_cost", "valid_play_of_mille", "千次有效播放数")
|
||||
_comment_column("material_cost", "valid_play_cost_of_mille", "千次有效播放成本(元)")
|
||||
_comment_column("material_cost", "average_play_time_per_play", "平均单次播放时长")
|
||||
_comment_column("material_cost", "play_over_rate", "完播率")
|
||||
_comment_column("material_cost", "dy_like", "点赞数")
|
||||
_comment_column("material_cost", "dy_comment", "评论量")
|
||||
_comment_column("material_cost", "dy_share", "分享量")
|
||||
_comment_column("material_cost", "report_cnt", "举报数")
|
||||
_comment_column("material_cost", "created_at", "创建时间")
|
||||
_comment_column("material_cost", "updated_at", "更新时间")
|
||||
_comment_column("material_cost", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# user_oauth 表
|
||||
# ============================================================
|
||||
_comment_table("user_oauth", "用户授权账户表(第三方平台授权)")
|
||||
_comment_column("user_oauth", "id", "主键")
|
||||
_comment_column("user_oauth", "account_id", "授权账户id")
|
||||
_comment_column("user_oauth", "account_name", "授权账户name")
|
||||
_comment_column("user_oauth", "account_role", "授权账户角色")
|
||||
_comment_column("user_oauth", "account_username", "授权账户登录账号")
|
||||
_comment_column("user_oauth", "account_userid", "授权账户登录userid")
|
||||
_comment_column("user_oauth", "user_id", "用户id")
|
||||
_comment_column("user_oauth", "open_type", "开户方式(1=千川,2=广告,3=本地推,4=星图,5=快手代理商,6=巨量星图,7=巨量服务单,8=腾讯服务单,9=腾讯营销K2,10=腾讯营销K3)")
|
||||
_comment_column("user_oauth", "port_type", "平台端口(1=巨量,2=磁力,3=巨量星图,4=服务单,5=腾讯)")
|
||||
_comment_column("user_oauth", "appid", "授权应用id")
|
||||
_comment_column("user_oauth", "access_token", "授权token")
|
||||
_comment_column("user_oauth", "access_token_expired", "token过期时间")
|
||||
_comment_column("user_oauth", "refresh_token", "授权刷新token")
|
||||
_comment_column("user_oauth", "refresh_token_expired", "刷新token过期时间")
|
||||
_comment_column("user_oauth", "material_auth_status", "是否敏感物料授权(true=是,false=否)")
|
||||
_comment_column("user_oauth", "created_at", "创建时间")
|
||||
_comment_column("user_oauth", "updated_at", "更新时间")
|
||||
_comment_column("user_oauth", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# user_oauth_account 表
|
||||
# ============================================================
|
||||
_comment_table("user_oauth_account", "授权账户详情表(广告账户映射)")
|
||||
_comment_column("user_oauth_account", "id", "主键")
|
||||
_comment_column("user_oauth_account", "oauth_id", "授权表中的id")
|
||||
_comment_column("user_oauth_account", "advertiser_id", "广告主账户id")
|
||||
_comment_column("user_oauth_account", "advertiser_name", "广告账户名")
|
||||
_comment_column("user_oauth_account", "advertiser_role", "广告账户类型")
|
||||
_comment_column("user_oauth_account", "created_at", "创建时间")
|
||||
_comment_column("user_oauth_account", "updated_at", "更新时间")
|
||||
_comment_column("user_oauth_account", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# user_oauth_app 表
|
||||
# ============================================================
|
||||
_comment_table("user_oauth_app", "授权应用管理表(应用密钥配置)")
|
||||
_comment_column("user_oauth_app", "id", "主键")
|
||||
_comment_column("user_oauth_app", "app_id", "应用id")
|
||||
_comment_column("user_oauth_app", "secret", "应用密钥")
|
||||
_comment_column("user_oauth_app", "status", "状态,1=正常,2=禁用")
|
||||
_comment_column("user_oauth_app", "max_count", "应用最大可以授权多少个用户")
|
||||
_comment_column("user_oauth_app", "auth_url", "应用授权链接")
|
||||
_comment_column("user_oauth_app", "company", "应用归属公司名称")
|
||||
_comment_column("user_oauth_app", "open_type", "开户方式")
|
||||
_comment_column("user_oauth_app", "create_by", "创建者")
|
||||
_comment_column("user_oauth_app", "created_at", "创建时间")
|
||||
_comment_column("user_oauth_app", "updated_at", "更新时间")
|
||||
_comment_column("user_oauth_app", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# upload_task 表
|
||||
# ============================================================
|
||||
_comment_table("upload_task", "上传任务表(素材上传记录)")
|
||||
_comment_column("upload_task", "id", "主键")
|
||||
_comment_column("upload_task", "user_id", "用户登录id")
|
||||
_comment_column("upload_task", "advertiser_id", "广告主id")
|
||||
_comment_column("upload_task", "resource_id", "资源id")
|
||||
_comment_column("upload_task", "status", "上传状态:1待上传,2上传中,3上传成功,4上传失败")
|
||||
_comment_column("upload_task", "note", "上传备注")
|
||||
_comment_column("upload_task", "oauth_id", "授权表id")
|
||||
_comment_column("upload_task", "other_info", "其他信息")
|
||||
_comment_column("upload_task", "created_at", "创建时间")
|
||||
_comment_column("upload_task", "updated_at", "更新时间")
|
||||
_comment_column("upload_task", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# user_resource_month_stats 表
|
||||
# ============================================================
|
||||
_comment_table("user_resource_month_stats", "用户月份资源空间聚合表")
|
||||
_comment_column("user_resource_month_stats", "id", "主键ID")
|
||||
_comment_column("user_resource_month_stats", "user_id", "所属用户ID")
|
||||
_comment_column("user_resource_month_stats", "stat_month", "统计月份")
|
||||
_comment_column("user_resource_month_stats", "active_size_bytes", "活跃资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "deleted_size_bytes", "已删除资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "total_generated_size_bytes", "累计生成资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "upload_size_bytes", "上传资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "image_size_bytes", "图片资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "video_size_bytes", "视频资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "audio_size_bytes", "音频资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "shot_segment_size_bytes", "拆镜切片资源大小(字节)")
|
||||
_comment_column("user_resource_month_stats", "active_count", "活跃资源数量")
|
||||
_comment_column("user_resource_month_stats", "deleted_count", "已删除资源数量")
|
||||
_comment_column("user_resource_month_stats", "image_count", "图片资源数量")
|
||||
_comment_column("user_resource_month_stats", "video_count", "视频资源数量")
|
||||
_comment_column("user_resource_month_stats", "upload_count", "上传资源数量")
|
||||
_comment_column("user_resource_month_stats", "audio_count", "音频资源数量")
|
||||
_comment_column("user_resource_month_stats", "shot_segment_count", "拆镜切片数量")
|
||||
_comment_column("user_resource_month_stats", "last_recalculated_at", "最后重新计算时间")
|
||||
_comment_column("user_resource_month_stats", "created_at", "创建时间")
|
||||
_comment_column("user_resource_month_stats", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# user_resource_total_stats 表
|
||||
# ============================================================
|
||||
_comment_table("user_resource_total_stats", "用户全局资源空间聚合表")
|
||||
_comment_column("user_resource_total_stats", "id", "主键ID")
|
||||
_comment_column("user_resource_total_stats", "user_id", "所属用户ID")
|
||||
_comment_column("user_resource_total_stats", "active_size_bytes", "活跃资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "deleted_size_bytes", "已删除资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "total_generated_size_bytes", "累计生成资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "upload_size_bytes", "上传资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "image_size_bytes", "图片资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "video_size_bytes", "视频资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "audio_size_bytes", "音频资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "shot_segment_size_bytes", "拆镜切片资源大小(字节)")
|
||||
_comment_column("user_resource_total_stats", "active_count", "活跃资源数量")
|
||||
_comment_column("user_resource_total_stats", "deleted_count", "已删除资源数量")
|
||||
_comment_column("user_resource_total_stats", "image_count", "图片资源数量")
|
||||
_comment_column("user_resource_total_stats", "video_count", "视频资源数量")
|
||||
_comment_column("user_resource_total_stats", "upload_count", "上传资源数量")
|
||||
_comment_column("user_resource_total_stats", "audio_count", "音频资源数量")
|
||||
_comment_column("user_resource_total_stats", "shot_segment_count", "拆镜切片数量")
|
||||
_comment_column("user_resource_total_stats", "last_recalculated_at", "最后重新计算时间")
|
||||
_comment_column("user_resource_total_stats", "created_at", "创建时间")
|
||||
_comment_column("user_resource_total_stats", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# home_material_assets 表
|
||||
# ============================================================
|
||||
_comment_table("home_material_assets", "首页素材资产表")
|
||||
_comment_column("home_material_assets", "id", "主键ID")
|
||||
_comment_column("home_material_assets", "category_id", "行业类别ID")
|
||||
_comment_column("home_material_assets", "title", "素材标题")
|
||||
_comment_column("home_material_assets", "media_type", "素材类型:image图片,video视频")
|
||||
_comment_column("home_material_assets", "original_url", "原始素材URL")
|
||||
_comment_column("home_material_assets", "original_storage_path", "原始素材本地路径")
|
||||
_comment_column("home_material_assets", "watermarked_url", "水印素材URL")
|
||||
_comment_column("home_material_assets", "watermarked_storage_path", "水印素材本地路径")
|
||||
_comment_column("home_material_assets", "cover_url", "视频封面URL")
|
||||
_comment_column("home_material_assets", "cover_storage_path", "视频封面本地路径")
|
||||
_comment_column("home_material_assets", "watermark_id", "水印图片ID")
|
||||
_comment_column("home_material_assets", "watermark_config_json", "水印配置快照JSON")
|
||||
_comment_column("home_material_assets", "generation_prompt", "生成提词")
|
||||
_comment_column("home_material_assets", "media_references_json", "附件/参考素材JSON字符串")
|
||||
_comment_column("home_material_assets", "status", "处理状态:draft/processing/success/failed")
|
||||
_comment_column("home_material_assets", "error_message", "处理失败原因")
|
||||
_comment_column("home_material_assets", "width", "素材宽度")
|
||||
_comment_column("home_material_assets", "height", "素材高度")
|
||||
_comment_column("home_material_assets", "duration_seconds", "视频时长,图片为空")
|
||||
_comment_column("home_material_assets", "file_size_bytes", "原始文件大小")
|
||||
_comment_column("home_material_assets", "watermarked_file_size_bytes", "水印后文件大小")
|
||||
_comment_column("home_material_assets", "is_active", "是否前台展示")
|
||||
_comment_column("home_material_assets", "sort_order", "排序,越小越靠前")
|
||||
_comment_column("home_material_assets", "processed_at", "处理完成时间")
|
||||
_comment_column("home_material_assets", "created_by", "创建管理员ID")
|
||||
_comment_column("home_material_assets", "updated_by", "更新管理员ID")
|
||||
_comment_column("home_material_assets", "created_at", "创建时间")
|
||||
_comment_column("home_material_assets", "updated_at", "更新时间")
|
||||
_comment_column("home_material_assets", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# home_material_categories 表
|
||||
# ============================================================
|
||||
_comment_table("home_material_categories", "首页素材行业类别表")
|
||||
_comment_column("home_material_categories", "id", "主键ID")
|
||||
_comment_column("home_material_categories", "name", "行业名称")
|
||||
_comment_column("home_material_categories", "key", "行业唯一标识,前台可按key查询")
|
||||
_comment_column("home_material_categories", "description", "行业描述")
|
||||
_comment_column("home_material_categories", "icon", "前端图标名称")
|
||||
_comment_column("home_material_categories", "is_active", "是否启用")
|
||||
_comment_column("home_material_categories", "sort_order", "排序,越小越靠前")
|
||||
_comment_column("home_material_categories", "created_by", "创建管理员ID")
|
||||
_comment_column("home_material_categories", "updated_by", "更新管理员ID")
|
||||
_comment_column("home_material_categories", "created_at", "创建时间")
|
||||
_comment_column("home_material_categories", "updated_at", "更新时间")
|
||||
_comment_column("home_material_categories", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# home_material_watermarks 表
|
||||
# ============================================================
|
||||
_comment_table("home_material_watermarks", "首页素材水印图片库")
|
||||
_comment_column("home_material_watermarks", "id", "主键ID")
|
||||
_comment_column("home_material_watermarks", "name", "水印名称")
|
||||
_comment_column("home_material_watermarks", "file_url", "水印图片URL")
|
||||
_comment_column("home_material_watermarks", "storage_path", "水印图片本地路径")
|
||||
_comment_column("home_material_watermarks", "file_name", "原始文件名")
|
||||
_comment_column("home_material_watermarks", "file_size_bytes", "文件大小")
|
||||
_comment_column("home_material_watermarks", "width", "水印图片宽度")
|
||||
_comment_column("home_material_watermarks", "height", "水印图片高度")
|
||||
_comment_column("home_material_watermarks", "is_default", "是否默认水印")
|
||||
_comment_column("home_material_watermarks", "is_active", "是否启用")
|
||||
_comment_column("home_material_watermarks", "created_by", "创建管理员ID")
|
||||
_comment_column("home_material_watermarks", "updated_by", "更新管理员ID")
|
||||
_comment_column("home_material_watermarks", "created_at", "创建时间")
|
||||
_comment_column("home_material_watermarks", "updated_at", "更新时间")
|
||||
_comment_column("home_material_watermarks", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# module_generation_projects 表
|
||||
# ============================================================
|
||||
_comment_table("module_generation_projects", "通用模块生成项目/总任务表")
|
||||
_comment_column("module_generation_projects", "id", "主键ID")
|
||||
_comment_column("module_generation_projects", "user_id", "所属用户ID")
|
||||
_comment_column("module_generation_projects", "module", "业务模块标识")
|
||||
_comment_column("module_generation_projects", "flow_version", "项目流程版本号")
|
||||
_comment_column("module_generation_projects", "title", "项目标题")
|
||||
_comment_column("module_generation_projects", "status", "项目状态:pending/processing/success/failed")
|
||||
_comment_column("module_generation_projects", "current_step_code", "当前执行步骤编码")
|
||||
_comment_column("module_generation_projects", "final_image_url", "最终生成图片URL")
|
||||
_comment_column("module_generation_projects", "final_video_url", "最终生成视频URL")
|
||||
_comment_column("module_generation_projects", "final_video_cover_url", "最终生成视频封面URL")
|
||||
_comment_column("module_generation_projects", "error_message", "错误信息")
|
||||
_comment_column("module_generation_projects", "idempotency_key", "幂等键")
|
||||
_comment_column("module_generation_projects", "completed_at", "项目完成时间")
|
||||
_comment_column("module_generation_projects", "created_at", "创建时间")
|
||||
_comment_column("module_generation_projects", "updated_at", "更新时间")
|
||||
_comment_column("module_generation_projects", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# module_generation_steps 表
|
||||
# ============================================================
|
||||
_comment_table("module_generation_steps", "通用模块生成步骤表")
|
||||
_comment_column("module_generation_steps", "id", "主键ID")
|
||||
_comment_column("module_generation_steps", "project_id", "所属项目ID")
|
||||
_comment_column("module_generation_steps", "user_id", "所属用户ID")
|
||||
_comment_column("module_generation_steps", "module", "业务模块标识")
|
||||
_comment_column("module_generation_steps", "step_index", "步骤序号")
|
||||
_comment_column("module_generation_steps", "step_code", "步骤编码")
|
||||
_comment_column("module_generation_steps", "status", "步骤状态:pending/processing/success/failed")
|
||||
_comment_column("module_generation_steps", "version", "步骤重建版本号")
|
||||
_comment_column("module_generation_steps", "is_current", "是否为当前版本")
|
||||
_comment_column("module_generation_steps", "parent_step_id", "父步骤ID")
|
||||
_comment_column("module_generation_steps", "source_step_id", "源步骤ID(复制来源)")
|
||||
_comment_column("module_generation_steps", "chat_task_id", "关联AI创作任务ID")
|
||||
_comment_column("module_generation_steps", "input_json", "步骤输入JSON")
|
||||
_comment_column("module_generation_steps", "output_json", "步骤输出JSON")
|
||||
_comment_column("module_generation_steps", "error_message", "错误信息")
|
||||
_comment_column("module_generation_steps", "started_at", "步骤开始时间")
|
||||
_comment_column("module_generation_steps", "completed_at", "步骤完成时间")
|
||||
_comment_column("module_generation_steps", "token_usage_id", "关联Token消耗记录ID")
|
||||
_comment_column("module_generation_steps", "model_config_id", "模型配置ID")
|
||||
_comment_column("module_generation_steps", "input_tokens", "输入Token数")
|
||||
_comment_column("module_generation_steps", "output_tokens", "输出Token数")
|
||||
_comment_column("module_generation_steps", "total_tokens", "总Token数")
|
||||
_comment_column("module_generation_steps", "text_credits_cost", "提示词优化消耗积分")
|
||||
_comment_column("module_generation_steps", "created_at", "创建时间")
|
||||
_comment_column("module_generation_steps", "updated_at", "更新时间")
|
||||
_comment_column("module_generation_steps", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# shot_replicate_segments 表
|
||||
# ============================================================
|
||||
_comment_table("shot_replicate_segments", "拆镜复刻片段表")
|
||||
_comment_column("shot_replicate_segments", "id", "主键ID")
|
||||
_comment_column("shot_replicate_segments", "task_set_id", "所属任务集ID")
|
||||
_comment_column("shot_replicate_segments", "user_id", "所属用户ID")
|
||||
_comment_column("shot_replicate_segments", "segment_index", "镜头序号")
|
||||
_comment_column("shot_replicate_segments", "source_mode", "来源模式:auto自动拆镜/manual手动")
|
||||
_comment_column("shot_replicate_segments", "start_second", "片段开始时间(秒)")
|
||||
_comment_column("shot_replicate_segments", "end_second", "片段结束时间(秒)")
|
||||
_comment_column("shot_replicate_segments", "duration_seconds", "片段时长(秒)")
|
||||
_comment_column("shot_replicate_segments", "time_node", "时间节点显示字符串")
|
||||
_comment_column("shot_replicate_segments", "split_status", "切片状态:pending/slicing/sliced/failed")
|
||||
_comment_column("shot_replicate_segments", "analysis_status", "AI分析状态:pending/processing/success/failed")
|
||||
_comment_column("shot_replicate_segments", "replicate_status", "复刻状态:not_started/processing/completed/failed")
|
||||
_comment_column("shot_replicate_segments", "segment_video_url", "片段视频访问URL")
|
||||
_comment_column("shot_replicate_segments", "segment_video_path", "片段视频存储路径")
|
||||
_comment_column("shot_replicate_segments", "original_video_content", "原视频内容描述")
|
||||
_comment_column("shot_replicate_segments", "original_video_category", "原视频行业分类")
|
||||
_comment_column("shot_replicate_segments", "original_video_audience", "原视频目标受众")
|
||||
_comment_column("shot_replicate_segments", "segment_content", "片段内容描述")
|
||||
_comment_column("shot_replicate_segments", "segment_category", "片段行业分类")
|
||||
_comment_column("shot_replicate_segments", "segment_audience", "片段目标受众")
|
||||
_comment_column("shot_replicate_segments", "analysis_json", "AI分析结果JSON")
|
||||
_comment_column("shot_replicate_segments", "ai_suggestion_json", "AI复刻建议JSON")
|
||||
_comment_column("shot_replicate_segments", "module_project_id", "关联模块生成项目ID")
|
||||
_comment_column("shot_replicate_segments", "split_claim_token", "切片租约token")
|
||||
_comment_column("shot_replicate_segments", "split_celery_task_id", "切片Celery任务ID")
|
||||
_comment_column("shot_replicate_segments", "split_enqueued_at", "切片入队时间")
|
||||
_comment_column("shot_replicate_segments", "split_started_at", "切片开始时间")
|
||||
_comment_column("shot_replicate_segments", "split_lease_until", "切片租约过期时间")
|
||||
_comment_column("shot_replicate_segments", "split_next_retry_at", "切片下次重试时间")
|
||||
_comment_column("shot_replicate_segments", "split_retry_count", "切片重试次数")
|
||||
_comment_column("shot_replicate_segments", "split_last_error", "切片最后错误信息")
|
||||
_comment_column("shot_replicate_segments", "split_completed_at", "切片完成时间")
|
||||
_comment_column("shot_replicate_segments", "analysis_attempt_no", "AI分析尝试次数")
|
||||
_comment_column("shot_replicate_segments", "analysis_claim_token", "AI分析租约token")
|
||||
_comment_column("shot_replicate_segments", "analysis_started_at", "AI分析开始时间")
|
||||
_comment_column("shot_replicate_segments", "analysis_lease_until", "AI分析租约过期")
|
||||
_comment_column("shot_replicate_segments", "analysis_error_message", "AI分析错误信息")
|
||||
_comment_column("shot_replicate_segments", "created_at", "创建时间")
|
||||
_comment_column("shot_replicate_segments", "updated_at", "更新时间")
|
||||
_comment_column("shot_replicate_segments", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# private_portrait_projects 表
|
||||
# ============================================================
|
||||
_comment_table("private_portrait_projects", "用户私域人像素材项目表")
|
||||
_comment_column("private_portrait_projects", "id", "主键ID")
|
||||
_comment_column("private_portrait_projects", "user_id", "所属用户ID")
|
||||
_comment_column("private_portrait_projects", "library_type", "素材库类型:real_person真人认证/aigc_virtual虚拟人像")
|
||||
_comment_column("private_portrait_projects", "name", "用户展示项目名")
|
||||
_comment_column("private_portrait_projects", "name_slug", "项目名安全slug")
|
||||
_comment_column("private_portrait_projects", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("private_portrait_projects", "description", "项目描述")
|
||||
_comment_column("private_portrait_projects", "status", "项目状态:active/creating/create_failed/deleting")
|
||||
_comment_column("private_portrait_projects", "asset_group_count", "素材分组数量")
|
||||
_comment_column("private_portrait_projects", "asset_count", "素材总数")
|
||||
_comment_column("private_portrait_projects", "image_asset_count", "图片素材数")
|
||||
_comment_column("private_portrait_projects", "video_asset_count", "视频素材数")
|
||||
_comment_column("private_portrait_projects", "active_asset_count", "有效素材数")
|
||||
_comment_column("private_portrait_projects", "active_image_asset_count", "有效图片素材数")
|
||||
_comment_column("private_portrait_projects", "active_video_asset_count", "有效视频素材数")
|
||||
_comment_column("private_portrait_projects", "last_used_at", "最后使用时间")
|
||||
_comment_column("private_portrait_projects", "created_at", "创建时间")
|
||||
_comment_column("private_portrait_projects", "updated_at", "更新时间")
|
||||
_comment_column("private_portrait_projects", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# private_portrait_asset_groups 表
|
||||
# ============================================================
|
||||
_comment_table("private_portrait_asset_groups", "本地项目组与火山Asset Group映射表")
|
||||
_comment_column("private_portrait_asset_groups", "id", "主键ID")
|
||||
_comment_column("private_portrait_asset_groups", "user_id", "所属用户ID")
|
||||
_comment_column("private_portrait_asset_groups", "project_id", "所属项目ID")
|
||||
_comment_column("private_portrait_asset_groups", "library_type", "素材库类型:real_person/aigc_virtual")
|
||||
_comment_column("private_portrait_asset_groups", "remote_group_id", "火山远端AssetGroup ID")
|
||||
_comment_column("private_portrait_asset_groups", "remote_group_name", "火山远端AssetGroup名称")
|
||||
_comment_column("private_portrait_asset_groups", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("private_portrait_asset_groups", "group_type", "分组类型")
|
||||
_comment_column("private_portrait_asset_groups", "status", "分组状态:active/creating/create_failed/deleting")
|
||||
_comment_column("private_portrait_asset_groups", "remote_delete_status", "远端删除状态:none/deleting/deleted/failed")
|
||||
_comment_column("private_portrait_asset_groups", "remote_deleted_at", "远端删除时间")
|
||||
_comment_column("private_portrait_asset_groups", "remote_delete_error", "远端删除错误")
|
||||
_comment_column("private_portrait_asset_groups", "raw_response_json", "火山原始响应JSON")
|
||||
_comment_column("private_portrait_asset_groups", "created_at", "创建时间")
|
||||
_comment_column("private_portrait_asset_groups", "updated_at", "更新时间")
|
||||
_comment_column("private_portrait_asset_groups", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# private_portrait_assets 表
|
||||
# ============================================================
|
||||
_comment_table("private_portrait_assets", "火山Asset本地映射表(素材文件记录)")
|
||||
_comment_column("private_portrait_assets", "id", "主键ID")
|
||||
_comment_column("private_portrait_assets", "user_id", "所属用户ID")
|
||||
_comment_column("private_portrait_assets", "project_id", "所属项目ID")
|
||||
_comment_column("private_portrait_assets", "group_id", "所属分组ID")
|
||||
_comment_column("private_portrait_assets", "library_type", "素材库类型:real_person/aigc_virtual")
|
||||
_comment_column("private_portrait_assets", "remote_group_id", "火山远端AssetGroup ID")
|
||||
_comment_column("private_portrait_assets", "remote_asset_id", "火山远端Asset ID")
|
||||
_comment_column("private_portrait_assets", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("private_portrait_assets", "asset_type", "素材类型:Image图片/Video视频")
|
||||
_comment_column("private_portrait_assets", "name", "素材名称")
|
||||
_comment_column("private_portrait_assets", "source_url", "本地上传后的访问URL")
|
||||
_comment_column("private_portrait_assets", "preview_url", "前端预览URL")
|
||||
_comment_column("private_portrait_assets", "remote_url", "火山返回的资源访问URL")
|
||||
_comment_column("private_portrait_assets", "remote_url_expired_at", "火山URL过期时间")
|
||||
_comment_column("private_portrait_assets", "video_duration", "视频素材时长,秒")
|
||||
_comment_column("private_portrait_assets", "video_cover_url", "视频素材封面预览地址")
|
||||
_comment_column("private_portrait_assets", "file_size", "素材文件大小,字节")
|
||||
_comment_column("private_portrait_assets", "mime_type", "MIME类型")
|
||||
_comment_column("private_portrait_assets", "status", "素材状态:creating/active/failed/deleting")
|
||||
_comment_column("private_portrait_assets", "moderation_json", "火山审核结果JSON")
|
||||
_comment_column("private_portrait_assets", "last_poll_at", "最后轮询时间")
|
||||
_comment_column("private_portrait_assets", "next_poll_at", "下次轮询时间")
|
||||
_comment_column("private_portrait_assets", "poll_count", "轮询次数")
|
||||
_comment_column("private_portrait_assets", "remote_delete_status", "远端删除状态:none/deleting/deleted/failed")
|
||||
_comment_column("private_portrait_assets", "remote_deleted_at", "远端删除时间")
|
||||
_comment_column("private_portrait_assets", "remote_delete_error", "远端删除错误")
|
||||
_comment_column("private_portrait_assets", "error_message", "错误信息")
|
||||
_comment_column("private_portrait_assets", "raw_response_json", "火山原始响应JSON")
|
||||
_comment_column("private_portrait_assets", "created_at", "创建时间")
|
||||
_comment_column("private_portrait_assets", "updated_at", "更新时间")
|
||||
_comment_column("private_portrait_assets", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# private_portrait_validate_sessions 表
|
||||
# ============================================================
|
||||
_comment_table("private_portrait_validate_sessions", "火山真人认证H5会话表")
|
||||
_comment_column("private_portrait_validate_sessions", "id", "主键ID")
|
||||
_comment_column("private_portrait_validate_sessions", "user_id", "所属用户ID")
|
||||
_comment_column("private_portrait_validate_sessions", "project_id", "关联项目ID")
|
||||
_comment_column("private_portrait_validate_sessions", "byted_token", "火山byted_token")
|
||||
_comment_column("private_portrait_validate_sessions", "h5_link", "认证H5链接")
|
||||
_comment_column("private_portrait_validate_sessions", "callback_url", "火山回调URL")
|
||||
_comment_column("private_portrait_validate_sessions", "result_code", "认证结果码")
|
||||
_comment_column("private_portrait_validate_sessions", "algorithm_base_resp_code", "算法基础响应码")
|
||||
_comment_column("private_portrait_validate_sessions", "verify_type", "认证类型")
|
||||
_comment_column("private_portrait_validate_sessions", "status", "会话状态:created/group_active/expired/failed")
|
||||
_comment_column("private_portrait_validate_sessions", "remote_group_id", "火山远端AssetGroup ID")
|
||||
_comment_column("private_portrait_validate_sessions", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("private_portrait_validate_sessions", "expired_at", "会话过期时间")
|
||||
_comment_column("private_portrait_validate_sessions", "error_message", "错误信息")
|
||||
_comment_column("private_portrait_validate_sessions", "raw_callback_json", "火山回调原始JSON")
|
||||
_comment_column("private_portrait_validate_sessions", "raw_response_json", "火山原始响应JSON")
|
||||
_comment_column("private_portrait_validate_sessions", "created_at", "创建时间")
|
||||
_comment_column("private_portrait_validate_sessions", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# vp_v3_projects 表
|
||||
# ============================================================
|
||||
_comment_table("vp_v3_projects", "API V3虚拟素材项目表(按API Key隔离)")
|
||||
_comment_column("vp_v3_projects", "id", "主键ID")
|
||||
_comment_column("vp_v3_projects", "api_key_id", "所属API Key(V3调用方)")
|
||||
_comment_column("vp_v3_projects", "name", "项目展示名称")
|
||||
_comment_column("vp_v3_projects", "name_slug", "名称安全slug(构建远端GroupName用)")
|
||||
_comment_column("vp_v3_projects", "description", "项目描述")
|
||||
_comment_column("vp_v3_projects", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("vp_v3_projects", "remote_group_id", "火山AssetGroup Id")
|
||||
_comment_column("vp_v3_projects", "remote_group_name", "火山AssetGroup Name快照")
|
||||
_comment_column("vp_v3_projects", "status", "项目状态:active/creating_remote_group/create_group_failed/deleting")
|
||||
_comment_column("vp_v3_projects", "asset_count", "素材总数")
|
||||
_comment_column("vp_v3_projects", "active_asset_count", "有效素材数")
|
||||
_comment_column("vp_v3_projects", "image_asset_count", "图片素材数")
|
||||
_comment_column("vp_v3_projects", "video_asset_count", "视频素材数")
|
||||
_comment_column("vp_v3_projects", "active_image_asset_count", "有效图片素材数")
|
||||
_comment_column("vp_v3_projects", "active_video_asset_count", "有效视频素材数")
|
||||
_comment_column("vp_v3_projects", "storage_mb_used", "项目占用存储MB")
|
||||
_comment_column("vp_v3_projects", "last_used_at", "最后使用时间")
|
||||
_comment_column("vp_v3_projects", "remote_delete_status", "远端删除状态")
|
||||
_comment_column("vp_v3_projects", "remote_deleted_at", "远端删除时间")
|
||||
_comment_column("vp_v3_projects", "remote_delete_error", "远端删除错误")
|
||||
_comment_column("vp_v3_projects", "error_message", "创建失败等错误信息")
|
||||
_comment_column("vp_v3_projects", "raw_response_json", "火山原始响应")
|
||||
_comment_column("vp_v3_projects", "created_at", "创建时间")
|
||||
_comment_column("vp_v3_projects", "updated_at", "更新时间")
|
||||
_comment_column("vp_v3_projects", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# vp_v3_assets 表
|
||||
# ============================================================
|
||||
_comment_table("vp_v3_assets", "API V3虚拟素材表(图片/视频)")
|
||||
_comment_column("vp_v3_assets", "id", "主键ID")
|
||||
_comment_column("vp_v3_assets", "api_key_id", "所属API Key")
|
||||
_comment_column("vp_v3_assets", "project_id", "所属项目ID")
|
||||
_comment_column("vp_v3_assets", "remote_project_name", "火山ProjectName快照")
|
||||
_comment_column("vp_v3_assets", "remote_group_id", "火山AssetGroup ID")
|
||||
_comment_column("vp_v3_assets", "remote_asset_id", "火山远端Asset ID")
|
||||
_comment_column("vp_v3_assets", "asset_type", "素材类型:Image=图片/Video=视频")
|
||||
_comment_column("vp_v3_assets", "name", "素材名称")
|
||||
_comment_column("vp_v3_assets", "source_url", "本地上传后的访问URL(UploadResource返回的)")
|
||||
_comment_column("vp_v3_assets", "preview_url", "给前端预览/显示用的URL")
|
||||
_comment_column("vp_v3_assets", "remote_url", "火山返回的资源访问URL")
|
||||
_comment_column("vp_v3_assets", "remote_url_expired_at", "火山URL过期时间")
|
||||
_comment_column("vp_v3_assets", "upload_resource_id", "本地UploadResource账本resource_id")
|
||||
_comment_column("vp_v3_assets", "video_duration", "视频时长,秒")
|
||||
_comment_column("vp_v3_assets", "video_cover_url", "视频封面预览")
|
||||
_comment_column("vp_v3_assets", "file_size_bytes", "素材文件大小,字节")
|
||||
_comment_column("vp_v3_assets", "mime_type", "MIME类型")
|
||||
_comment_column("vp_v3_assets", "status", "素材状态:creating/审核中active/可用failed/失败deleting/删除中")
|
||||
_comment_column("vp_v3_assets", "moderation_json", "火山审核结果JSON")
|
||||
_comment_column("vp_v3_assets", "error_message", "失败原因")
|
||||
_comment_column("vp_v3_assets", "raw_response_json", "火山原始响应JSON")
|
||||
_comment_column("vp_v3_assets", "last_poll_at", "最后轮询时间")
|
||||
_comment_column("vp_v3_assets", "next_poll_at", "下次轮询时间")
|
||||
_comment_column("vp_v3_assets", "poll_count", "轮询次数")
|
||||
_comment_column("vp_v3_assets", "remote_delete_status", "远端删除状态")
|
||||
_comment_column("vp_v3_assets", "remote_deleted_at", "远端删除时间")
|
||||
_comment_column("vp_v3_assets", "remote_delete_error", "远端删除错误")
|
||||
_comment_column("vp_v3_assets", "created_at", "创建时间")
|
||||
_comment_column("vp_v3_assets", "updated_at", "更新时间")
|
||||
_comment_column("vp_v3_assets", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# vp_v3_api_key_quotas 表
|
||||
# ============================================================
|
||||
_comment_table("vp_v3_api_key_quotas", "API V3虚拟素材库配额表(每个ApiKey一份)")
|
||||
_comment_column("vp_v3_api_key_quotas", "id", "主键ID")
|
||||
_comment_column("vp_v3_api_key_quotas", "api_key_id", "所属API Key,唯一:一个API Key只有一份虚拟素材配额")
|
||||
_comment_column("vp_v3_api_key_quotas", "project_limit", "虚拟项目上限,默认0不可创建")
|
||||
_comment_column("vp_v3_api_key_quotas", "asset_limit", "虚拟素材总数上限(图片+视频),默认0不可上传")
|
||||
_comment_column("vp_v3_api_key_quotas", "storage_mb_limit", "上传存储上限MB,默认0不可上传文件")
|
||||
_comment_column("vp_v3_api_key_quotas", "project_used", "已创建项目数(未删除)")
|
||||
_comment_column("vp_v3_api_key_quotas", "asset_used", "已上传素材数(未删除,图片+视频)")
|
||||
_comment_column("vp_v3_api_key_quotas", "storage_mb_used", "已占用存储MB(未删除文件大小合计)")
|
||||
_comment_column("vp_v3_api_key_quotas", "remark", "后台备注")
|
||||
_comment_column("vp_v3_api_key_quotas", "created_at", "创建时间")
|
||||
_comment_column("vp_v3_api_key_quotas", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# api_keys 表
|
||||
# ============================================================
|
||||
_comment_table("api_keys", "对外开放API密钥管理表")
|
||||
_comment_column("api_keys", "id", "主键ID")
|
||||
_comment_column("api_keys", "company_name", "公司/组织名称")
|
||||
_comment_column("api_keys", "api_key_hash", "API Key哈希值,唯一")
|
||||
_comment_column("api_keys", "api_key_prefix", "API Key前缀")
|
||||
_comment_column("api_keys", "api_key_encrypted", "AES-256-GCM加密的完整API Key")
|
||||
_comment_column("api_keys", "description", "描述信息")
|
||||
_comment_column("api_keys", "callable_models", "可调用模型配置JSON数组")
|
||||
_comment_column("api_keys", "quota_limit", "配额总量,NULL=无限")
|
||||
_comment_column("api_keys", "quota_cycle", "配额周期:daily/monthly/one_time/NULL=无限")
|
||||
_comment_column("api_keys", "quota_used", "当前周期已使用量")
|
||||
_comment_column("api_keys", "valid_from", "有效期开始时间")
|
||||
_comment_column("api_keys", "valid_until", "有效期结束时间")
|
||||
_comment_column("api_keys", "max_concurrent_video_tasks", "最大并发视频任务数,NULL=无限")
|
||||
_comment_column("api_keys", "is_active", "是否启用")
|
||||
_comment_column("api_keys", "last_used_at", "最后使用时间")
|
||||
_comment_column("api_keys", "created_at", "创建时间")
|
||||
_comment_column("api_keys", "updated_at", "更新时间")
|
||||
_comment_column("api_keys", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# api_generation_tasks 表
|
||||
# ============================================================
|
||||
_comment_table("api_generation_tasks", "对外开放API生成任务表")
|
||||
_comment_column("api_generation_tasks", "id", "主键ID")
|
||||
_comment_column("api_generation_tasks", "api_key_id", "所属API Key")
|
||||
_comment_column("api_generation_tasks", "external_idempotency_key", "外部幂等键")
|
||||
_comment_column("api_generation_tasks", "original_prompt", "原始提示词")
|
||||
_comment_column("api_generation_tasks", "optimized_prompt", "优化后的提示词")
|
||||
_comment_column("api_generation_tasks", "gen_type", "生成类型:image/video")
|
||||
_comment_column("api_generation_tasks", "duration", "视频时长(秒)")
|
||||
_comment_column("api_generation_tasks", "aspect_ratio", "视频比例")
|
||||
_comment_column("api_generation_tasks", "resolution", "分辨率档位")
|
||||
_comment_column("api_generation_tasks", "provider_generation_resolution", "供应商实际生成分辨率")
|
||||
_comment_column("api_generation_tasks", "image_size", "图片分辨率档位")
|
||||
_comment_column("api_generation_tasks", "image_proportion", "图片比例")
|
||||
_comment_column("api_generation_tasks", "image_px", "图片像素")
|
||||
_comment_column("api_generation_tasks", "generation_count", "生成份数")
|
||||
_comment_column("api_generation_tasks", "engine_id", "引擎ID")
|
||||
_comment_column("api_generation_tasks", "model_name", "模型名称")
|
||||
_comment_column("api_generation_tasks", "media_references", "用户原始上传的媒体URL")
|
||||
_comment_column("api_generation_tasks", "local_media_json", "下载到本地的媒体文件路径JSON")
|
||||
_comment_column("api_generation_tasks", "engine_snapshot_json", "引擎参数快照JSON")
|
||||
_comment_column("api_generation_tasks", "request_params_json", "完整原始请求参数")
|
||||
_comment_column("api_generation_tasks", "status", "任务状态")
|
||||
_comment_column("api_generation_tasks", "pipeline_stage", "流水线阶段")
|
||||
_comment_column("api_generation_tasks", "generation_attempt_no", "生成尝试次数")
|
||||
_comment_column("api_generation_tasks", "resource_generation_started_at", "资源生成开始时间")
|
||||
_comment_column("api_generation_tasks", "deadline_at", "任务截止时间")
|
||||
_comment_column("api_generation_tasks", "provider_task_id", "供应商任务ID")
|
||||
_comment_column("api_generation_tasks", "remote_result_url", "供应商远程资源URL")
|
||||
_comment_column("api_generation_tasks", "provider_response_json", "供应商响应JSON")
|
||||
_comment_column("api_generation_tasks", "image_url", "图片结果URL")
|
||||
_comment_column("api_generation_tasks", "video_url", "视频结果URL")
|
||||
_comment_column("api_generation_tasks", "video_cover_url", "视频封面URL")
|
||||
_comment_column("api_generation_tasks", "error_message", "错误信息")
|
||||
_comment_column("api_generation_tasks", "generated_at", "生成完成时间")
|
||||
_comment_column("api_generation_tasks", "video_upscale_enabled_snapshot", "是否开启视频超分")
|
||||
_comment_column("api_generation_tasks", "video_upscale_snapshot_json", "视频超分参数快照JSON")
|
||||
_comment_column("api_generation_tasks", "credits_cost", "消耗积分")
|
||||
_comment_column("api_generation_tasks", "video_tokens_used", "视频Token消耗")
|
||||
_comment_column("api_generation_tasks", "image_tokens_used", "图片Token消耗")
|
||||
_comment_column("api_generation_tasks", "next_poll_at", "下次轮询时间")
|
||||
_comment_column("api_generation_tasks", "poll_interval_seconds", "轮询间隔秒数")
|
||||
_comment_column("api_generation_tasks", "poll_count", "轮询次数")
|
||||
_comment_column("api_generation_tasks", "last_poll_at", "最后轮询时间")
|
||||
_comment_column("api_generation_tasks", "provider_create_claim_token", "供应商创建任务租约token")
|
||||
_comment_column("api_generation_tasks", "provider_create_lease_until", "供应商创建租约过期")
|
||||
_comment_column("api_generation_tasks", "provider_create_started_at", "供应商创建开始时间")
|
||||
_comment_column("api_generation_tasks", "poll_started_at", "轮询开始时间")
|
||||
_comment_column("api_generation_tasks", "poll_claim_token", "轮询租约token")
|
||||
_comment_column("api_generation_tasks", "poll_lease_until", "轮询租约过期")
|
||||
_comment_column("api_generation_tasks", "poll_error_count", "轮询错误次数")
|
||||
_comment_column("api_generation_tasks", "download_celery_task_id", "下载Celery任务ID")
|
||||
_comment_column("api_generation_tasks", "download_enqueued_at", "下载入队时间")
|
||||
_comment_column("api_generation_tasks", "download_started_at", "下载开始时间")
|
||||
_comment_column("api_generation_tasks", "download_claim_token", "下载租约token")
|
||||
_comment_column("api_generation_tasks", "download_lease_until", "下载租约过期")
|
||||
_comment_column("api_generation_tasks", "download_next_retry_at", "下载下次重试时间")
|
||||
_comment_column("api_generation_tasks", "download_attempt_count", "下载重试次数")
|
||||
_comment_column("api_generation_tasks", "download_last_error", "下载最后错误信息")
|
||||
_comment_column("api_generation_tasks", "download_storage_date_dir", "下载存储日期目录")
|
||||
_comment_column("api_generation_tasks", "local_path", "本地存储路径")
|
||||
_comment_column("api_generation_tasks", "created_at", "创建时间")
|
||||
_comment_column("api_generation_tasks", "updated_at", "更新时间")
|
||||
_comment_column("api_generation_tasks", "deleted_at", "软删除时间,NULL表示未删除")
|
||||
|
||||
# ============================================================
|
||||
# api_usage_logs 表
|
||||
# ============================================================
|
||||
_comment_table("api_usage_logs", "API调用详细消耗记录表")
|
||||
_comment_column("api_usage_logs", "id", "主键ID")
|
||||
_comment_column("api_usage_logs", "api_key_id", "所属API Key")
|
||||
_comment_column("api_usage_logs", "api_generation_task_id", "关联生成任务ID")
|
||||
_comment_column("api_usage_logs", "price_action", "操作类型:deduct=扣除, refund=退回")
|
||||
_comment_column("api_usage_logs", "request_type", "请求类型:video_create/image_generate")
|
||||
_comment_column("api_usage_logs", "model_name", "模型名称")
|
||||
_comment_column("api_usage_logs", "gen_type", "生成类型:image/video")
|
||||
_comment_column("api_usage_logs", "resolution", "分辨率")
|
||||
_comment_column("api_usage_logs", "duration", "视频时长(秒)")
|
||||
_comment_column("api_usage_logs", "credits_cost", "实际扣除金额")
|
||||
_comment_column("api_usage_logs", "refund_amount", "退回金额")
|
||||
_comment_column("api_usage_logs", "quota_before", "操作前配额余额")
|
||||
_comment_column("api_usage_logs", "quota_after", "操作后配额余额")
|
||||
_comment_column("api_usage_logs", "tokens_used", "Token用量")
|
||||
_comment_column("api_usage_logs", "request_duration_ms", "端到端耗时")
|
||||
_comment_column("api_usage_logs", "price_detail_json", "价格计算明细JSON")
|
||||
_comment_column("api_usage_logs", "status", "调用状态:success/failed")
|
||||
_comment_column("api_usage_logs", "error_message", "错误信息")
|
||||
_comment_column("api_usage_logs", "error_code", "错误码")
|
||||
_comment_column("api_usage_logs", "request_payload_json", "原始请求快照")
|
||||
_comment_column("api_usage_logs", "created_at", "创建时间")
|
||||
_comment_column("api_usage_logs", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# api_model_pricings 表
|
||||
# ============================================================
|
||||
_comment_table("api_model_pricings", "API模型价格表(全局统一配置)")
|
||||
_comment_column("api_model_pricings", "id", "主键ID")
|
||||
_comment_column("api_model_pricings", "model_config_id", "引擎ID:图片对应image_engines.id,视频对应video_engines.id")
|
||||
_comment_column("api_model_pricings", "gen_type", "生成类型:image/video")
|
||||
_comment_column("api_model_pricings", "resolution", "分辨率档位")
|
||||
_comment_column("api_model_pricings", "price_ratio", "价格系数(乘数)")
|
||||
_comment_column("api_model_pricings", "base_price", "基础价格(元)")
|
||||
_comment_column("api_model_pricings", "per_second_price", "每秒价格(视频,元)")
|
||||
_comment_column("api_model_pricings", "input_video_ratio", "传入视频系数")
|
||||
_comment_column("api_model_pricings", "input_video_base_price", "传入视频基础价(元)")
|
||||
_comment_column("api_model_pricings", "input_video_per_second_price", "传入视频每秒价(元)")
|
||||
_comment_column("api_model_pricings", "input_image_ratio", "传入图片系数")
|
||||
_comment_column("api_model_pricings", "input_image_base_price", "传入图片基础价(元)")
|
||||
_comment_column("api_model_pricings", "input_image_per_image_price", "传入图片每张价(元)")
|
||||
_comment_column("api_model_pricings", "created_at", "创建时间")
|
||||
_comment_column("api_model_pricings", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# api_upscale_links 表
|
||||
# ============================================================
|
||||
_comment_table("api_upscale_links", "API任务与超分任务关联表")
|
||||
_comment_column("api_upscale_links", "id", "主键ID")
|
||||
_comment_column("api_upscale_links", "api_generation_task_id", "关联API生成任务ID")
|
||||
_comment_column("api_upscale_links", "video_upscale_task_id", "关联视频超分任务ID")
|
||||
_comment_column("api_upscale_links", "created_at", "创建时间")
|
||||
_comment_column("api_upscale_links", "updated_at", "更新时间")
|
||||
|
||||
# ============================================================
|
||||
# api_key_upscale_configs 表
|
||||
# ============================================================
|
||||
_comment_table("api_key_upscale_configs", "API Key级别超分配置表")
|
||||
_comment_column("api_key_upscale_configs", "id", "主键ID")
|
||||
_comment_column("api_key_upscale_configs", "api_key_id", "所属API Key")
|
||||
_comment_column("api_key_upscale_configs", "enabled", "是否启用超分")
|
||||
_comment_column("api_key_upscale_configs", "delete_source_after_success", "超分成功后是否删除源文件")
|
||||
_comment_column("api_key_upscale_configs", "rules_json", "超分规则JSON数组")
|
||||
_comment_column("api_key_upscale_configs", "created_at", "创建时间")
|
||||
_comment_column("api_key_upscale_configs", "updated_at", "更新时间")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.execute("""
|
||||
DO $$
|
||||
DECLARE
|
||||
r record;
|
||||
BEGIN
|
||||
FOR r IN
|
||||
SELECT table_name, column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name IN (
|
||||
'notification_reads', 'menu_configs',
|
||||
'team_join_requests', 'team_invitations',
|
||||
'contact_requests', 'token_usage',
|
||||
'industry_configs', 'chat_generation_task_events',
|
||||
'chat_provider_call_logs', 'open_type',
|
||||
'pre_test_template', 'material_cost',
|
||||
'user_oauth', 'user_oauth_account', 'user_oauth_app',
|
||||
'upload_task', 'user_resource_month_stats',
|
||||
'user_resource_total_stats', 'home_material_assets',
|
||||
'home_material_categories', 'home_material_watermarks',
|
||||
'module_generation_projects', 'module_generation_steps',
|
||||
'shot_replicate_segments',
|
||||
'private_portrait_projects', 'private_portrait_asset_groups',
|
||||
'private_portrait_assets', 'private_portrait_validate_sessions',
|
||||
'vp_v3_projects', 'vp_v3_assets', 'vp_v3_api_key_quotas',
|
||||
'api_keys', 'api_generation_tasks', 'api_usage_logs',
|
||||
'api_model_pricings', 'api_upscale_links',
|
||||
'api_key_upscale_configs'
|
||||
)
|
||||
LOOP
|
||||
EXECUTE format('COMMENT ON COLUMN %I.%I IS NULL', r.table_name, r.column_name);
|
||||
END LOOP;
|
||||
END $$;
|
||||
""")
|
||||
for t in [
|
||||
"notification_reads", "menu_configs",
|
||||
"team_join_requests", "team_invitations",
|
||||
"contact_requests", "token_usage",
|
||||
"industry_configs", "chat_generation_task_events",
|
||||
"chat_provider_call_logs", "open_type",
|
||||
"pre_test_template", "material_cost",
|
||||
"user_oauth", "user_oauth_account", "user_oauth_app",
|
||||
"upload_task", "user_resource_month_stats",
|
||||
"user_resource_total_stats", "home_material_assets",
|
||||
"home_material_categories", "home_material_watermarks",
|
||||
"module_generation_projects", "module_generation_steps",
|
||||
"shot_replicate_segments",
|
||||
"private_portrait_projects", "private_portrait_asset_groups",
|
||||
"private_portrait_assets", "private_portrait_validate_sessions",
|
||||
"vp_v3_projects", "vp_v3_assets", "vp_v3_api_key_quotas",
|
||||
"api_keys", "api_generation_tasks", "api_usage_logs",
|
||||
"api_model_pricings", "api_upscale_links",
|
||||
"api_key_upscale_configs",
|
||||
]:
|
||||
op.execute(f"COMMENT ON TABLE {t} IS NULL")
|
||||
@@ -0,0 +1,109 @@
|
||||
"""发票管理表迁移
|
||||
|
||||
创建 invoices(发票主表)和 invoice_orders(发票-订单关联表)。
|
||||
|
||||
Revision ID: 20260810_20260810
|
||||
Revises: 2026080601
|
||||
Create Date: 2026-08-10 00:00:00.000000
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision: str = '20260810_20260810'
|
||||
down_revision: Union[str, None] = '2026080601'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def _comment_table(table_name: str, comment: str) -> None:
|
||||
op.execute(f"COMMENT ON TABLE {table_name} IS '{comment}'")
|
||||
|
||||
|
||||
def _comment_column(table_name: str, column_name: str, comment: str) -> None:
|
||||
escaped = comment.replace("'", "''")
|
||||
op.execute(f"COMMENT ON COLUMN {table_name}.{column_name} IS '{escaped}'")
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ============================================================
|
||||
# 1. 创建 invoices 表
|
||||
# ============================================================
|
||||
op.create_table(
|
||||
'invoices',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('user_id', sa.String(32), sa.ForeignKey('users.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('invoice_no', sa.String(32), nullable=False, unique=True),
|
||||
sa.Column('header_type', sa.String(16), nullable=False),
|
||||
sa.Column('header_name', sa.String(128), nullable=False),
|
||||
sa.Column('header_tax_no', sa.String(32), nullable=True),
|
||||
sa.Column('header_register_address', sa.String(256), nullable=True),
|
||||
sa.Column('header_register_phone', sa.String(32), nullable=True),
|
||||
sa.Column('header_bank_name', sa.String(128), nullable=True),
|
||||
sa.Column('header_bank_account', sa.String(64), nullable=True),
|
||||
sa.Column('email', sa.String(128), nullable=False),
|
||||
sa.Column('total_amount', sa.Float, nullable=False, server_default='0'),
|
||||
sa.Column('total_credits', sa.Float, nullable=False, server_default='0'),
|
||||
sa.Column('status', sa.String(16), nullable=False, server_default='processing'),
|
||||
sa.Column('failure_reason', sa.Text, nullable=True),
|
||||
sa.Column('issued_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
op.create_index('idx_invoices_user_created', 'invoices', ['user_id', 'created_at'])
|
||||
op.create_index('idx_invoices_status_created', 'invoices', ['status', 'created_at'])
|
||||
op.create_index('idx_invoices_invoice_no', 'invoices', ['invoice_no'], unique=True)
|
||||
|
||||
# ============================================================
|
||||
# 2. 创建 invoice_orders 表
|
||||
# ============================================================
|
||||
op.create_table(
|
||||
'invoice_orders',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('invoice_id', sa.String(32), sa.ForeignKey('invoices.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('order_id', sa.String(32), sa.ForeignKey('payment_orders.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('order_no', sa.String(64), nullable=False),
|
||||
sa.Column('amount', sa.Float, nullable=False, server_default='0'),
|
||||
sa.Column('credits', sa.Float, nullable=False, server_default='0'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
op.create_index('idx_invoice_orders_invoice', 'invoice_orders', ['invoice_id'])
|
||||
op.create_index('idx_invoice_orders_order', 'invoice_orders', ['order_id'])
|
||||
op.create_unique_constraint('uq_invoice_orders', 'invoice_orders', ['invoice_id', 'order_id'])
|
||||
|
||||
# ============================================================
|
||||
# 3. 表注释和字段注释
|
||||
# ============================================================
|
||||
_comment_table('invoices', '发票主表')
|
||||
_comment_column('invoices', 'id', '主键')
|
||||
_comment_column('invoices', 'user_id', '申请用户ID')
|
||||
_comment_column('invoices', 'invoice_no', '发票编号')
|
||||
_comment_column('invoices', 'header_type', '抬头类型: personal/company')
|
||||
_comment_column('invoices', 'header_name', '抬头名称')
|
||||
_comment_column('invoices', 'header_tax_no', '税号')
|
||||
_comment_column('invoices', 'header_register_address', '注册地址')
|
||||
_comment_column('invoices', 'header_register_phone', '注册电话')
|
||||
_comment_column('invoices', 'header_bank_name', '开户行')
|
||||
_comment_column('invoices', 'header_bank_account', '银行账号')
|
||||
_comment_column('invoices', 'email', '电子邮箱(必填)')
|
||||
_comment_column('invoices', 'total_amount', '开票总金额')
|
||||
_comment_column('invoices', 'total_credits', '总积分')
|
||||
_comment_column('invoices', 'status', '状态: processing/success/failed')
|
||||
_comment_column('invoices', 'failure_reason', '失败原因')
|
||||
_comment_column('invoices', 'issued_at', '开票成功时间')
|
||||
|
||||
_comment_table('invoice_orders', '发票-订单关联表')
|
||||
_comment_column('invoice_orders', 'id', '主键')
|
||||
_comment_column('invoice_orders', 'invoice_id', '发票ID')
|
||||
_comment_column('invoice_orders', 'order_id', '订单ID')
|
||||
_comment_column('invoice_orders', 'order_no', '订单号(冗余)')
|
||||
_comment_column('invoice_orders', 'amount', '订单金额(冗余)')
|
||||
_comment_column('invoice_orders', 'credits', '订单积分(冗余)')
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table('invoice_orders')
|
||||
op.drop_table('invoices')
|
||||
@@ -0,0 +1,65 @@
|
||||
"""发票抬头表迁移
|
||||
|
||||
创建 invoice_headers(发票抬头表),用于用户管理常用发票抬头。
|
||||
|
||||
Revision ID: 20260811_20260811
|
||||
Revises: 20260810_20260810
|
||||
Create Date: 2026-08-11 00:00:00.000000
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision: str = '20260811_20260811'
|
||||
down_revision: Union[str, None] = '20260810_20260810'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def _comment_table(table_name: str, comment: str) -> None:
|
||||
op.execute(f"COMMENT ON TABLE {table_name} IS '{comment}'")
|
||||
|
||||
|
||||
def _comment_column(table_name: str, column_name: str, comment: str) -> None:
|
||||
escaped = comment.replace("'", "''")
|
||||
op.execute(f"COMMENT ON COLUMN {table_name}.{column_name} IS '{escaped}'")
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
'invoice_headers',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('user_id', sa.String(32), sa.ForeignKey('users.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('type', sa.String(16), nullable=False),
|
||||
sa.Column('name', sa.String(128), nullable=False),
|
||||
sa.Column('tax_no', sa.String(32), nullable=True),
|
||||
sa.Column('register_address', sa.String(256), nullable=True),
|
||||
sa.Column('register_phone', sa.String(32), nullable=True),
|
||||
sa.Column('bank_name', sa.String(128), nullable=True),
|
||||
sa.Column('bank_account', sa.String(64), nullable=True),
|
||||
sa.Column('email', sa.String(128), nullable=True),
|
||||
sa.Column('is_default', sa.Boolean, nullable=False, server_default='false'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
op.create_index('idx_invoice_headers_user', 'invoice_headers', ['user_id'])
|
||||
|
||||
# 表注释和字段注释
|
||||
_comment_table('invoice_headers', '发票抬头表')
|
||||
_comment_column('invoice_headers', 'id', '主键')
|
||||
_comment_column('invoice_headers', 'user_id', '用户ID')
|
||||
_comment_column('invoice_headers', 'type', '抬头类型: personal/company')
|
||||
_comment_column('invoice_headers', 'name', '抬头名称')
|
||||
_comment_column('invoice_headers', 'tax_no', '税号')
|
||||
_comment_column('invoice_headers', 'register_address', '注册地址')
|
||||
_comment_column('invoice_headers', 'register_phone', '注册电话')
|
||||
_comment_column('invoice_headers', 'bank_name', '开户行')
|
||||
_comment_column('invoice_headers', 'bank_account', '银行账号')
|
||||
_comment_column('invoice_headers', 'email', '接收邮箱')
|
||||
_comment_column('invoice_headers', 'is_default', '是否默认')
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table('invoice_headers')
|
||||
@@ -0,0 +1,194 @@
|
||||
"""add api v3 tables (api_keys, api_generation_tasks, api_usage_logs, api_key_upscale_configs, api_upscale_links)
|
||||
|
||||
Revision ID: a1b2c3d4e5f6
|
||||
Revises: 20da1d353914
|
||||
Create Date: 2026-07-28 12:00:00.000000
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'a1b2c3d4e5f6g'
|
||||
down_revision: Union[str, None] = '20da1d353914'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# === 1. api_keys ===
|
||||
op.create_table(
|
||||
'api_keys',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('company_name', sa.String(128), nullable=False),
|
||||
sa.Column('api_key_hash', sa.String(64), nullable=False, unique=True),
|
||||
sa.Column('api_key_prefix', sa.String(16), nullable=False),
|
||||
sa.Column('description', sa.Text, nullable=True),
|
||||
sa.Column('callable_models', sa.Text, nullable=False, server_default='[]'),
|
||||
sa.Column('quota_limit', sa.Float, nullable=True),
|
||||
sa.Column('quota_cycle', sa.String(16), nullable=True),
|
||||
sa.Column('quota_used', sa.Float, nullable=False, server_default='0.0'),
|
||||
sa.Column('valid_from', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('valid_until', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('max_concurrent_video_tasks', sa.Integer, nullable=True),
|
||||
sa.Column('is_active', sa.Boolean, nullable=False, server_default='true'),
|
||||
sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
op.create_index('idx_api_key_hash', 'api_keys', ['api_key_hash'], unique=True)
|
||||
op.create_index('idx_api_keys_active', 'api_keys', ['is_active'])
|
||||
op.create_index('idx_api_keys_company', 'api_keys', ['company_name'])
|
||||
|
||||
# === 2. api_generation_tasks ===
|
||||
op.create_table(
|
||||
'api_generation_tasks',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('api_key_id', sa.String(32), sa.ForeignKey('api_keys.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('external_idempotency_key', sa.String(64), nullable=True),
|
||||
sa.Column('original_prompt', sa.Text, nullable=False),
|
||||
sa.Column('optimized_prompt', sa.Text, nullable=True),
|
||||
sa.Column('gen_type', sa.String(16), nullable=False, default='video'),
|
||||
sa.Column('duration', sa.Integer, nullable=True),
|
||||
sa.Column('aspect_ratio', sa.String(8), nullable=True),
|
||||
sa.Column('resolution', sa.String(8), nullable=True),
|
||||
sa.Column('provider_generation_resolution', sa.String(16), nullable=True),
|
||||
sa.Column('image_size', sa.String(16), nullable=True),
|
||||
sa.Column('image_proportion', sa.String(8), nullable=True),
|
||||
sa.Column('image_px', sa.String(16), nullable=True),
|
||||
sa.Column('generation_count', sa.Integer, nullable=False, default=1, server_default='1'),
|
||||
sa.Column('engine_id', sa.String(32), nullable=True),
|
||||
sa.Column('media_references', sa.Text, nullable=True),
|
||||
sa.Column('engine_snapshot_json', sa.Text, nullable=True),
|
||||
sa.Column('request_params_json', sa.Text, nullable=True),
|
||||
sa.Column('status', sa.String(32), nullable=False, default='pending'),
|
||||
sa.Column('pipeline_stage', sa.String(32), nullable=True),
|
||||
sa.Column('generation_attempt_no', sa.Integer, nullable=False, default=1, server_default='1'),
|
||||
sa.Column('resource_generation_started_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('deadline_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('provider_task_id', sa.String(128), nullable=True),
|
||||
sa.Column('remote_result_url', sa.Text, nullable=True),
|
||||
sa.Column('provider_response_json', sa.Text, nullable=True),
|
||||
sa.Column('image_url', sa.String(512), nullable=True),
|
||||
sa.Column('video_url', sa.String(512), nullable=True),
|
||||
sa.Column('video_cover_url', sa.String(512), nullable=True),
|
||||
sa.Column('video_upscale_enabled_snapshot', sa.Boolean, nullable=False, default=False, server_default='false'),
|
||||
sa.Column('video_upscale_snapshot_json', sa.Text, nullable=True),
|
||||
sa.Column('credits_cost', sa.Float, nullable=False, default=0.0, server_default='0.0'),
|
||||
sa.Column('video_tokens_used', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('image_tokens_used', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('error_message', sa.Text, nullable=True),
|
||||
sa.Column('generated_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('next_poll_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('poll_interval_seconds', sa.Integer, nullable=False, default=30, server_default='30'),
|
||||
sa.Column('poll_count', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('last_poll_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('provider_create_claim_token', sa.String(64), nullable=True),
|
||||
sa.Column('provider_create_lease_until', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('provider_create_started_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('poll_started_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('poll_claim_token', sa.String(64), nullable=True),
|
||||
sa.Column('poll_lease_until', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('poll_error_count', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('download_celery_task_id', sa.String(160), nullable=True),
|
||||
sa.Column('download_enqueued_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('download_started_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('download_claim_token', sa.String(64), nullable=True),
|
||||
sa.Column('download_lease_until', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('download_next_retry_at', sa.DateTime(timezone=True), nullable=True),
|
||||
sa.Column('download_attempt_count', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('download_last_error', sa.Text, nullable=True),
|
||||
sa.Column('download_storage_date_dir', sa.String(16), nullable=True),
|
||||
sa.Column('local_path', sa.Text, nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
op.create_index('idx_api_generation_tasks_api_key', 'api_generation_tasks', ['api_key_id'])
|
||||
op.create_index('idx_api_generation_tasks_status', 'api_generation_tasks', ['status'])
|
||||
op.create_index('idx_api_generation_tasks_provider_task_id', 'api_generation_tasks', ['provider_task_id'])
|
||||
op.create_index('idx_api_generation_tasks_next_poll_at', 'api_generation_tasks', ['next_poll_at'])
|
||||
op.create_index('idx_api_generation_tasks_api_key_created', 'api_generation_tasks', ['api_key_id', 'created_at'])
|
||||
op.create_index(
|
||||
'uq_api_generation_tasks_key_idempotency',
|
||||
'api_generation_tasks',
|
||||
['api_key_id', 'external_idempotency_key'],
|
||||
unique=True,
|
||||
postgresql_where=sa.text("deleted_at IS NULL AND external_idempotency_key IS NOT NULL"),
|
||||
)
|
||||
|
||||
# === 3. api_usage_logs ===
|
||||
op.create_table(
|
||||
'api_usage_logs',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('api_key_id', sa.String(32), sa.ForeignKey('api_keys.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('api_generation_task_id', sa.String(32), sa.ForeignKey('api_generation_tasks.id', ondelete='SET NULL'), nullable=True),
|
||||
sa.Column('request_type', sa.String(32), nullable=False),
|
||||
sa.Column('model_name', sa.String(128), nullable=False),
|
||||
sa.Column('gen_type', sa.String(16), nullable=False),
|
||||
sa.Column('credits_cost', sa.Float, nullable=False, default=0.0, server_default='0.0'),
|
||||
sa.Column('tokens_used', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('request_duration_ms', sa.Integer, nullable=False, default=0, server_default='0'),
|
||||
sa.Column('status', sa.String(32), nullable=False),
|
||||
sa.Column('error_message', sa.Text, nullable=True),
|
||||
sa.Column('error_code', sa.String(64), nullable=True),
|
||||
sa.Column('request_payload_json', sa.Text, nullable=True),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
op.create_index('idx_api_usage_logs_api_key', 'api_usage_logs', ['api_key_id'])
|
||||
op.create_index('idx_api_usage_logs_task_id', 'api_usage_logs', ['api_generation_task_id'])
|
||||
op.create_index('idx_api_usage_logs_api_key_created', 'api_usage_logs', ['api_key_id', 'created_at'])
|
||||
|
||||
# === 4. api_key_upscale_configs ===
|
||||
op.create_table(
|
||||
'api_key_upscale_configs',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('api_key_id', sa.String(32), sa.ForeignKey('api_keys.id', ondelete='CASCADE'), nullable=False, unique=True),
|
||||
sa.Column('enabled', sa.Boolean, nullable=False, default=False, server_default='false'),
|
||||
sa.Column('delete_source_after_success', sa.Boolean, nullable=False, default=True, server_default='true'),
|
||||
sa.Column('rules_json', sa.Text, nullable=False, server_default='[]'),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
|
||||
# === 5. api_upscale_links ===
|
||||
op.create_table(
|
||||
'api_upscale_links',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('api_generation_task_id', sa.String(32), sa.ForeignKey('api_generation_tasks.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('video_upscale_task_id', sa.String(32), sa.ForeignKey('video_upscale_tasks.id', ondelete='CASCADE'), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False),
|
||||
)
|
||||
op.create_index('idx_api_upscale_links_api_task', 'api_upscale_links', ['api_generation_task_id'])
|
||||
op.create_index('idx_api_upscale_links_video_task', 'api_upscale_links', ['video_upscale_task_id'])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index('idx_api_upscale_links_video_task', table_name='api_upscale_links')
|
||||
op.drop_index('idx_api_upscale_links_api_task', table_name='api_upscale_links')
|
||||
op.drop_table('api_upscale_links')
|
||||
|
||||
op.drop_table('api_key_upscale_configs')
|
||||
|
||||
op.drop_index('idx_api_usage_logs_api_key_created', table_name='api_usage_logs')
|
||||
op.drop_index('idx_api_usage_logs_task_id', table_name='api_usage_logs')
|
||||
op.drop_index('idx_api_usage_logs_api_key', table_name='api_usage_logs')
|
||||
op.drop_table('api_usage_logs')
|
||||
|
||||
op.drop_index('uq_api_generation_tasks_key_idempotency', table_name='api_generation_tasks')
|
||||
op.drop_index('idx_api_generation_tasks_api_key_created', table_name='api_generation_tasks')
|
||||
op.drop_index('idx_api_generation_tasks_next_poll_at', table_name='api_generation_tasks')
|
||||
op.drop_index('idx_api_generation_tasks_provider_task_id', table_name='api_generation_tasks')
|
||||
op.drop_index('idx_api_generation_tasks_status', table_name='api_generation_tasks')
|
||||
op.drop_index('idx_api_generation_tasks_api_key', table_name='api_generation_tasks')
|
||||
op.drop_table('api_generation_tasks')
|
||||
|
||||
op.drop_index('idx_api_keys_company', table_name='api_keys')
|
||||
op.drop_index('idx_api_keys_active', table_name='api_keys')
|
||||
op.drop_index('idx_api_key_hash', table_name='api_keys')
|
||||
op.drop_table('api_keys')
|
||||
@@ -0,0 +1,56 @@
|
||||
"""add api_model_pricings table
|
||||
|
||||
Revision ID: b2c3d4e5f6g7
|
||||
Revises: a1b2c3d4e5f6
|
||||
Create Date: 2026-07-28 14:00:00.000000
|
||||
|
||||
API 模型价格表 - 使用直接金额(元)计费,镜像 credit_ratios 结构。
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'b2c3d4e5f6g7h'
|
||||
down_revision: Union[str, None] = 'a1b2c3d4e5f6g'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.create_table(
|
||||
'api_model_pricings',
|
||||
sa.Column('id', sa.String(32), primary_key=True),
|
||||
sa.Column('model_config_id', sa.String(32), nullable=False, index=True),
|
||||
sa.Column('gen_type', sa.String(16), nullable=False, default='video', index=True),
|
||||
sa.Column('resolution', sa.String(16), nullable=False, index=True),
|
||||
sa.Column('price_ratio', sa.Float, nullable=False, default=1.0),
|
||||
sa.Column('base_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('per_second_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('input_video_ratio', sa.Float, nullable=False, default=1.0),
|
||||
sa.Column('input_video_base_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('input_video_per_second_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('input_image_ratio', sa.Float, nullable=False, default=1.0),
|
||||
sa.Column('input_image_base_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('input_image_per_image_price', sa.Float, nullable=False, default=0.0),
|
||||
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now()),
|
||||
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), onupdate=sa.func.now()),
|
||||
)
|
||||
op.create_index(
|
||||
'ix_api_model_pricings_gen_type_engine_resolution',
|
||||
'api_model_pricings',
|
||||
['gen_type', 'model_config_id', 'resolution'],
|
||||
)
|
||||
op.create_index(
|
||||
'ix_api_model_pricings_gen_type_resolution',
|
||||
'api_model_pricings',
|
||||
['gen_type', 'resolution'],
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index('ix_api_model_pricings_gen_type_resolution', table_name='api_model_pricings')
|
||||
op.drop_index('ix_api_model_pricings_gen_type_engine_resolution', table_name='api_model_pricings')
|
||||
op.drop_table('api_model_pricings')
|
||||
@@ -0,0 +1,33 @@
|
||||
"""add api_key_encrypted column to api_keys
|
||||
|
||||
Revision ID: c3d4e5f6g7h8
|
||||
Revises: b2c3d4e5f6g7h
|
||||
Create Date: 2026-07-28 16:00:00.000000
|
||||
|
||||
添加 api_key_encrypted 字段用于存储加密的完整 API Key,支持随时揭秘复制。
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'c3d4e5f6g7h8'
|
||||
down_revision: Union[str, None] = 'b2c3d4e5f6g7h'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
'api_keys',
|
||||
sa.Column('api_key_encrypted', sa.Text, nullable=True, comment='AES-256-GCM 加密的完整 API Key'),
|
||||
)
|
||||
# 为现有记录设置空值(新创建的 Key 会自动加密)
|
||||
op.execute("UPDATE api_keys SET api_key_encrypted = '' WHERE api_key_encrypted IS NULL")
|
||||
op.alter_column('api_keys', 'api_key_encrypted', nullable=False)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column('api_keys', 'api_key_encrypted')
|
||||
@@ -0,0 +1,29 @@
|
||||
"""add model_name to api_generation_tasks
|
||||
|
||||
Revision ID: c4d5e6f7g8h9
|
||||
Revises: c3d4e5f6g7h8
|
||||
Create Date: 2026-07-29 16:00:00.000000
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'c4d5e6f7g8h9'
|
||||
down_revision: Union[str, None] = 'c3d4e5f6g7h8'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
'api_generation_tasks',
|
||||
sa.Column('model_name', sa.String(128), nullable=False, server_default='', comment="模型名称,如 doubao-seedance-2-0-260128"),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column('api_generation_tasks', 'model_name')
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
"""add api_generation_task_id to video_upscale_tasks
|
||||
|
||||
Revision ID: d5e6f7g8h9i0
|
||||
Revises: c4d5e6f7g8h9
|
||||
Create Date: 2026-07-29 16:30:00.000000
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'd5e6f7g8h9i0'
|
||||
down_revision: Union[str, None] = 'c4d5e6f7g8h9'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# 添加 api_generation_task_id 字段
|
||||
op.add_column(
|
||||
'video_upscale_tasks',
|
||||
sa.Column('api_generation_task_id', sa.String(32), nullable=True, comment="API v3 任务ID,关联 api_generation_tasks.id"),
|
||||
)
|
||||
op.create_index(
|
||||
'idx_video_upscale_tasks_api_generation_task_id',
|
||||
'video_upscale_tasks',
|
||||
['api_generation_task_id'],
|
||||
)
|
||||
op.create_foreign_key(
|
||||
'fk_video_upscale_tasks_api_generation_task_id',
|
||||
'video_upscale_tasks',
|
||||
'api_generation_tasks',
|
||||
['api_generation_task_id'],
|
||||
['id'],
|
||||
ondelete='CASCADE',
|
||||
)
|
||||
|
||||
# 删除旧的检查约束,创建新的(允许 api_generation_task_id)
|
||||
op.execute("ALTER TABLE video_upscale_tasks DROP CONSTRAINT IF EXISTS ck_video_upscale_tasks_exactly_one_owner")
|
||||
op.execute("""
|
||||
ALTER TABLE video_upscale_tasks
|
||||
ADD CONSTRAINT ck_video_upscale_tasks_exactly_one_owner
|
||||
CHECK (
|
||||
(chat_generation_task_id IS NOT NULL)::int +
|
||||
(generation_record_id IS NOT NULL)::int +
|
||||
(api_generation_task_id IS NOT NULL)::int = 1
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# 恢复旧约束
|
||||
op.execute("ALTER TABLE video_upscale_tasks DROP CONSTRAINT IF EXISTS ck_video_upscale_tasks_exactly_one_owner")
|
||||
op.execute("""
|
||||
ALTER TABLE video_upscale_tasks
|
||||
ADD CONSTRAINT ck_video_upscale_tasks_exactly_one_owner
|
||||
CHECK (
|
||||
(chat_generation_task_id IS NOT NULL)::int +
|
||||
(generation_record_id IS NOT NULL)::int = 1
|
||||
)
|
||||
""")
|
||||
|
||||
op.drop_constraint('fk_video_upscale_tasks_api_generation_task_id', 'video_upscale_tasks', type_='foreignkey')
|
||||
op.drop_index('idx_video_upscale_tasks_api_generation_task_id', table_name='video_upscale_tasks')
|
||||
op.drop_column('video_upscale_tasks', 'api_generation_task_id')
|
||||
@@ -0,0 +1,43 @@
|
||||
"""enhance api_usage_logs with detailed consumption fields
|
||||
|
||||
Revision ID: e6f7g8h9i0j1
|
||||
Revises: d5e6f7g8h9i0
|
||||
Create Date: 2026-07-29 17:00:00.000000
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'e6f7g8h9i0j1'
|
||||
down_revision: Union[str, None] = 'd5e6f7g8h9i0'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# 添加新字段
|
||||
op.add_column('api_usage_logs', sa.Column('price_action', sa.String(16), nullable=False, server_default='deduct', comment='deduct=扣除, refund=退回'))
|
||||
op.add_column('api_usage_logs', sa.Column('resolution', sa.String(16), nullable=True, comment="分辨率: 480p/720p/1080p/2K/4K"))
|
||||
op.add_column('api_usage_logs', sa.Column('duration', sa.Integer(), nullable=True, comment="视频时长(秒)"))
|
||||
op.add_column('api_usage_logs', sa.Column('refund_amount', sa.Float(), nullable=False, server_default='0.0', comment='退回金额'))
|
||||
op.add_column('api_usage_logs', sa.Column('quota_before', sa.Float(), nullable=True, comment='操作前配额余额'))
|
||||
op.add_column('api_usage_logs', sa.Column('quota_after', sa.Float(), nullable=True, comment='操作后配额余额'))
|
||||
op.add_column('api_usage_logs', sa.Column('price_detail_json', sa.Text(), nullable=True, comment='价格计算明细JSON'))
|
||||
|
||||
# 添加索引
|
||||
op.create_index('idx_api_usage_logs_action', 'api_usage_logs', ['price_action'])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_index('idx_api_usage_logs_action', table_name='api_usage_logs')
|
||||
op.drop_column('api_usage_logs', 'price_detail_json')
|
||||
op.drop_column('api_usage_logs', 'quota_after')
|
||||
op.drop_column('api_usage_logs', 'quota_before')
|
||||
op.drop_column('api_usage_logs', 'refund_amount')
|
||||
op.drop_column('api_usage_logs', 'duration')
|
||||
op.drop_column('api_usage_logs', 'resolution')
|
||||
op.drop_column('api_usage_logs', 'price_action')
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
"""add local_media_json to api_generation_tasks
|
||||
|
||||
Revision ID: f7g8h9i0j1k2
|
||||
Revises: e6f7g8h9i0j1
|
||||
Create Date: 2026-07-29 18:00:00.000000
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'f7g8h9i0j1k2'
|
||||
down_revision: Union[str, None] = 'e6f7g8h9i0j1'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
'api_generation_tasks',
|
||||
sa.Column('local_media_json', sa.Text, nullable=True, comment='下载到本地的媒体文件路径JSON'),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column('api_generation_tasks', 'local_media_json')
|
||||
Reference in New Issue
Block a user