"""创建脚本引擎相关表 Revision ID: 003 Revises: 002 Create Date: 2025-01-11 12:00:00.000000 """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import mysql # revision identifiers, used by Alembic. revision = '003' down_revision = '002' branch_labels = None depends_on = None def upgrade(): """创建脚本引擎相关表""" # 创建脚本项目表 op.create_table('vwed_script_project', sa.Column('id', sa.Integer(), nullable=False, comment='项目ID'), sa.Column('project_name', sa.String(100), nullable=False, comment='项目名称'), sa.Column('project_path', sa.String(500), nullable=False, comment='项目路径'), sa.Column('description', sa.Text(), nullable=True, comment='项目描述'), sa.Column('status', sa.String(20), nullable=False, server_default='active', comment='项目状态'), sa.Column('created_by', sa.String(100), nullable=True, comment='创建者'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'), sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('project_path'), comment='脚本项目表' ) # 创建脚本文件表 op.create_table('vwed_script_file', sa.Column('id', sa.Integer(), nullable=False, comment='文件ID'), sa.Column('project_id', sa.Integer(), nullable=False, comment='所属项目ID'), sa.Column('file_name', sa.String(255), nullable=False, comment='文件名'), sa.Column('file_path', sa.String(500), nullable=False, comment='文件相对路径'), sa.Column('file_type', sa.String(20), nullable=False, server_default='python', comment='文件类型'), sa.Column('content', sa.Text(), nullable=True, comment='文件内容'), sa.Column('size', sa.Integer(), nullable=True, server_default='0', comment='文件大小'), sa.Column('encoding', sa.String(20), nullable=True, server_default='utf-8', comment='文件编码'), sa.Column('is_directory', sa.Boolean(), nullable=True, server_default='0', comment='是否为目录'), sa.Column('is_executable', sa.Boolean(), nullable=True, server_default='0', comment='是否可执行'), sa.Column('has_boot_function', sa.Boolean(), nullable=True, server_default='0', comment='是否包含boot函数'), sa.Column('status', sa.String(20), nullable=False, server_default='active', comment='文件状态'), sa.Column('created_by', sa.String(100), nullable=True, comment='创建者'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'), sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'), sa.ForeignKeyConstraint(['project_id'], ['vwed_script_project.id'], ), sa.PrimaryKeyConstraint('id'), comment='脚本文件表' ) # 创建脚本注册中心表 op.create_table('vwed_script_registry', sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'), sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'), sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'), sa.Column('script_path', sa.String(500), nullable=False, comment='脚本相对路径'), sa.Column('status', sa.String(20), nullable=False, server_default='starting', comment='运行状态'), sa.Column('process_id', sa.String(50), nullable=True, comment='进程ID'), sa.Column('host_info', sa.JSON(), nullable=True, comment='主机信息'), sa.Column('start_params', sa.JSON(), nullable=True, comment='启动参数'), sa.Column('resource_limits', sa.JSON(), nullable=True, comment='资源限制配置'), sa.Column('performance_stats', sa.JSON(), nullable=True, comment='性能统计信息'), sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'), sa.Column('api_count', sa.Integer(), nullable=True, server_default='0', comment='注册的API数量'), sa.Column('function_count', sa.Integer(), nullable=True, server_default='0', comment='注册的函数数量'), sa.Column('event_count', sa.Integer(), nullable=True, server_default='0', comment='注册的事件监听器数量'), sa.Column('timer_count', sa.Integer(), nullable=True, server_default='0', comment='注册的定时任务数量'), sa.Column('last_heartbeat', sa.DateTime(), nullable=True, comment='最后心跳时间'), sa.Column('started_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='启动时间'), sa.Column('stopped_at', sa.DateTime(), nullable=True, comment='停止时间'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'), sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'), sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('script_id'), comment='脚本注册中心表' ) # 创建脚本执行日志表 op.create_table('vwed_script_execution_log', sa.Column('id', sa.Integer(), nullable=False, comment='日志ID'), sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'), sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'), sa.Column('execution_type', sa.String(50), nullable=False, comment='执行类型'), sa.Column('function_name', sa.String(255), nullable=True, comment='执行的函数名'), sa.Column('input_params', sa.JSON(), nullable=True, comment='输入参数'), sa.Column('output_result', sa.JSON(), nullable=True, comment='输出结果'), sa.Column('status', sa.String(20), nullable=False, comment='执行状态'), sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'), sa.Column('error_traceback', sa.Text(), nullable=True, comment='错误堆栈'), sa.Column('start_time', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='开始时间'), sa.Column('end_time', sa.DateTime(), nullable=True, comment='结束时间'), sa.Column('duration_ms', sa.Integer(), nullable=True, comment='执行时长'), sa.Column('memory_usage_mb', sa.Float(), nullable=True, comment='内存使用'), sa.Column('cpu_usage_percent', sa.Float(), nullable=True, comment='CPU使用率'), sa.Column('log_level', sa.String(20), nullable=True, server_default='INFO', comment='日志级别'), sa.Column('tags', sa.JSON(), nullable=True, comment='标签信息'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'), sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ), sa.PrimaryKeyConstraint('id'), comment='脚本执行日志表' ) # 创建API注册记录表 op.create_table('vwed_script_api_registration', sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'), sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'), sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'), sa.Column('route_path', sa.String(500), nullable=False, comment='路由路径'), sa.Column('http_method', sa.String(20), nullable=False, comment='HTTP方法'), sa.Column('handler_name', sa.String(255), nullable=False, comment='处理函数名'), sa.Column('description', sa.Text(), nullable=True, comment='接口描述'), sa.Column('parameters', sa.JSON(), nullable=True, comment='接口参数定义'), sa.Column('response_schema', sa.JSON(), nullable=True, comment='响应格式定义'), sa.Column('is_active', sa.Boolean(), nullable=True, server_default='1', comment='是否激活'), sa.Column('call_count', sa.Integer(), nullable=True, server_default='0', comment='调用次数'), sa.Column('last_called_at', sa.DateTime(), nullable=True, comment='最后调用时间'), sa.Column('average_response_time_ms', sa.Integer(), nullable=True, comment='平均响应时间'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='注册时间'), sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ), sa.PrimaryKeyConstraint('id'), comment='API注册记录表' ) # 创建函数注册记录表 op.create_table('vwed_script_function_registration', sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'), sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'), sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'), sa.Column('function_name', sa.String(255), nullable=False, comment='函数名'), sa.Column('handler_name', sa.String(255), nullable=False, comment='处理函数名'), sa.Column('description', sa.Text(), nullable=True, comment='函数描述'), sa.Column('parameters', sa.JSON(), nullable=True, comment='参数定义'), sa.Column('return_schema', sa.JSON(), nullable=True, comment='返回值格式定义'), sa.Column('is_async', sa.Boolean(), nullable=True, server_default='0', comment='是否为异步函数'), sa.Column('is_active', sa.Boolean(), nullable=True, server_default='1', comment='是否激活'), sa.Column('call_count', sa.Integer(), nullable=True, server_default='0', comment='调用次数'), sa.Column('last_called_at', sa.DateTime(), nullable=True, comment='最后调用时间'), sa.Column('average_execution_time_ms', sa.Integer(), nullable=True, comment='平均执行时间'), sa.Column('success_count', sa.Integer(), nullable=True, server_default='0', comment='成功执行次数'), sa.Column('error_count', sa.Integer(), nullable=True, server_default='0', comment='错误次数'), sa.Column('tags', sa.JSON(), nullable=True, comment='函数标签'), sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='注册时间'), sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ), sa.PrimaryKeyConstraint('id'), comment='函数注册记录表' ) # 创建索引 op.create_index('idx_script_file_project_path', 'vwed_script_file', ['project_id', 'file_path']) op.create_index('idx_script_registry_script_id', 'vwed_script_registry', ['script_id']) op.create_index('idx_script_registry_status', 'vwed_script_registry', ['status']) op.create_index('idx_execution_log_script_id', 'vwed_script_execution_log', ['script_id']) op.create_index('idx_execution_log_status', 'vwed_script_execution_log', ['status']) op.create_index('idx_api_registration_script_id', 'vwed_script_api_registration', ['script_id']) op.create_index('idx_api_registration_route', 'vwed_script_api_registration', ['route_path', 'http_method']) op.create_index('idx_function_registration_script_id', 'vwed_script_function_registration', ['script_id']) op.create_index('idx_function_registration_name', 'vwed_script_function_registration', ['function_name']) def downgrade(): """删除脚本引擎相关表""" # 删除索引 op.drop_index('idx_function_registration_name', table_name='vwed_script_function_registration') op.drop_index('idx_function_registration_script_id', table_name='vwed_script_function_registration') op.drop_index('idx_api_registration_route', table_name='vwed_script_api_registration') op.drop_index('idx_api_registration_script_id', table_name='vwed_script_api_registration') op.drop_index('idx_execution_log_status', table_name='vwed_script_execution_log') op.drop_index('idx_execution_log_script_id', table_name='vwed_script_execution_log') op.drop_index('idx_script_registry_status', table_name='vwed_script_registry') op.drop_index('idx_script_registry_script_id', table_name='vwed_script_registry') op.drop_index('idx_script_file_project_path', table_name='vwed_script_file') # 删除表(按依赖关系逆序删除) op.drop_table('vwed_script_function_registration') op.drop_table('vwed_script_api_registration') op.drop_table('vwed_script_execution_log') op.drop_table('vwed_script_registry') op.drop_table('vwed_script_file') op.drop_table('vwed_script_project')