"""Initial migration Revision ID: 424646027786 Revises: Create Date: 2025-12-16 09:56:45.172954 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '424646027786' down_revision: Union[str, Sequence[str], None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: """Upgrade schema.""" # ### commands auto generated by Alembic - please adjust! ### op.create_table('agent_configs', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=100), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('enabled_tools', sa.JSON(), nullable=False), sa.Column('max_iterations', sa.Integer(), nullable=False), sa.Column('temperature', sa.String(length=10), nullable=False), sa.Column('system_message', sa.Text(), nullable=True), sa.Column('verbose', sa.Boolean(), nullable=False), sa.Column('model_name', sa.String(length=100), nullable=False), sa.Column('max_tokens', sa.Integer(), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('is_default', sa.Boolean(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_agent_configs')) ) op.create_index(op.f('ix_agent_configs_id'), 'agent_configs', ['id'], unique=False) op.create_index(op.f('ix_agent_configs_name'), 'agent_configs', ['name'], unique=False) op.create_table('conversations', sa.Column('title', sa.String(length=200), nullable=False), sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('knowledge_base_id', sa.Integer(), nullable=True), sa.Column('system_prompt', sa.Text(), nullable=True), sa.Column('model_name', sa.String(length=100), nullable=False), sa.Column('temperature', sa.String(length=10), nullable=False), sa.Column('max_tokens', sa.Integer(), nullable=False), sa.Column('is_archived', sa.Boolean(), nullable=False), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_conversations')) ) op.create_index(op.f('ix_conversations_id'), 'conversations', ['id'], unique=False) op.create_table('database_configs', sa.Column('id', sa.Integer(), nullable=False), sa.Column('name', sa.String(length=100), nullable=False), sa.Column('db_type', sa.String(length=20), nullable=False), sa.Column('host', sa.String(length=255), nullable=False), sa.Column('port', sa.Integer(), nullable=False), sa.Column('database', sa.String(length=100), nullable=False), sa.Column('username', sa.String(length=100), nullable=False), sa.Column('password', sa.Text(), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('is_default', sa.Boolean(), nullable=False), sa.Column('connection_params', sa.JSON(), nullable=True), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_database_configs')), sa.UniqueConstraint('db_type', name=op.f('uq_database_configs_db_type')) ) op.create_index(op.f('ix_database_configs_id'), 'database_configs', ['id'], unique=False) op.create_table('documents', sa.Column('knowledge_base_id', sa.Integer(), nullable=False), sa.Column('filename', sa.String(length=255), nullable=False), sa.Column('original_filename', sa.String(length=255), nullable=False), sa.Column('file_path', sa.String(length=500), nullable=False), sa.Column('file_size', sa.Integer(), nullable=False), sa.Column('file_type', sa.String(length=50), nullable=False), sa.Column('mime_type', sa.String(length=100), nullable=True), sa.Column('is_processed', sa.Boolean(), nullable=False), sa.Column('processing_error', sa.Text(), nullable=True), sa.Column('content', sa.Text(), nullable=True), sa.Column('doc_metadata', sa.JSON(), nullable=True), sa.Column('chunk_count', sa.Integer(), nullable=False), sa.Column('embedding_model', sa.String(length=100), nullable=True), sa.Column('vector_ids', sa.JSON(), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_documents')) ) op.create_index(op.f('ix_documents_id'), 'documents', ['id'], unique=False) op.create_table('excel_files', sa.Column('original_filename', sa.String(length=255), nullable=False), sa.Column('file_path', sa.String(length=500), nullable=False), sa.Column('file_size', sa.Integer(), nullable=False), sa.Column('file_type', sa.String(length=50), nullable=False), sa.Column('sheet_names', sa.JSON(), nullable=False), sa.Column('default_sheet', sa.String(length=100), nullable=True), sa.Column('columns_info', sa.JSON(), nullable=False), sa.Column('preview_data', sa.JSON(), nullable=False), sa.Column('data_types', sa.JSON(), nullable=True), sa.Column('total_rows', sa.JSON(), nullable=True), sa.Column('total_columns', sa.JSON(), nullable=True), sa.Column('is_processed', sa.Boolean(), nullable=False), sa.Column('processing_error', sa.Text(), nullable=True), sa.Column('last_accessed', sa.DateTime(), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_excel_files')) ) op.create_index(op.f('ix_excel_files_id'), 'excel_files', ['id'], unique=False) op.create_table('knowledge_bases', sa.Column('name', sa.String(length=100), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('embedding_model', sa.String(length=100), nullable=False), sa.Column('chunk_size', sa.Integer(), nullable=False), sa.Column('chunk_overlap', sa.Integer(), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('vector_db_type', sa.String(length=50), nullable=False), sa.Column('collection_name', sa.String(length=100), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_knowledge_bases')) ) op.create_index(op.f('ix_knowledge_bases_id'), 'knowledge_bases', ['id'], unique=False) op.create_index(op.f('ix_knowledge_bases_name'), 'knowledge_bases', ['name'], unique=False) op.create_table('llm_configs', sa.Column('name', sa.String(length=100), nullable=False), sa.Column('provider', sa.String(length=50), nullable=False), sa.Column('model_name', sa.String(length=100), nullable=False), sa.Column('api_key', sa.String(length=500), nullable=False), sa.Column('base_url', sa.String(length=200), nullable=True), sa.Column('max_tokens', sa.Integer(), nullable=False), sa.Column('temperature', sa.Float(), nullable=False), sa.Column('top_p', sa.Float(), nullable=False), sa.Column('frequency_penalty', sa.Float(), nullable=False), sa.Column('presence_penalty', sa.Float(), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('is_default', sa.Boolean(), nullable=False), sa.Column('is_embedding', sa.Boolean(), nullable=False), sa.Column('extra_config', sa.JSON(), nullable=True), sa.Column('usage_count', sa.Integer(), nullable=False), sa.Column('last_used_at', sa.DateTime(), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_llm_configs')) ) op.create_index(op.f('ix_llm_configs_id'), 'llm_configs', ['id'], unique=False) op.create_index(op.f('ix_llm_configs_name'), 'llm_configs', ['name'], unique=False) op.create_index(op.f('ix_llm_configs_provider'), 'llm_configs', ['provider'], unique=False) op.create_table('messages', sa.Column('conversation_id', sa.Integer(), nullable=False), sa.Column('role', sa.Enum('USER', 'ASSISTANT', 'SYSTEM', name='messagerole'), nullable=False), sa.Column('content', sa.Text(), nullable=False), sa.Column('message_type', sa.Enum('TEXT', 'IMAGE', 'FILE', 'AUDIO', name='messagetype'), nullable=False), sa.Column('message_metadata', sa.JSON(), nullable=True), sa.Column('context_documents', sa.JSON(), nullable=True), sa.Column('prompt_tokens', sa.Integer(), nullable=True), sa.Column('completion_tokens', sa.Integer(), nullable=True), sa.Column('total_tokens', sa.Integer(), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_messages')) ) op.create_index(op.f('ix_messages_id'), 'messages', ['id'], unique=False) op.create_table('roles', sa.Column('name', sa.String(length=100), nullable=False), sa.Column('code', sa.String(length=100), nullable=False), sa.Column('description', sa.Text(), nullable=True), sa.Column('is_system', sa.Boolean(), nullable=False), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_roles')) ) op.create_index(op.f('ix_roles_code'), 'roles', ['code'], unique=True) op.create_index(op.f('ix_roles_id'), 'roles', ['id'], unique=False) op.create_index(op.f('ix_roles_name'), 'roles', ['name'], unique=True) op.create_table('table_metadata', sa.Column('id', sa.Integer(), nullable=False), sa.Column('table_name', sa.String(length=100), nullable=False), sa.Column('table_schema', sa.String(length=50), nullable=False), sa.Column('table_type', sa.String(length=20), nullable=False), sa.Column('table_comment', sa.Text(), nullable=True), sa.Column('database_config_id', sa.Integer(), nullable=True), sa.Column('columns_info', sa.JSON(), nullable=False), sa.Column('primary_keys', sa.JSON(), nullable=True), sa.Column('foreign_keys', sa.JSON(), nullable=True), sa.Column('indexes', sa.JSON(), nullable=True), sa.Column('sample_data', sa.JSON(), nullable=True), sa.Column('row_count', sa.Integer(), nullable=False), sa.Column('is_enabled_for_qa', sa.Boolean(), nullable=False), sa.Column('qa_description', sa.Text(), nullable=True), sa.Column('business_context', sa.Text(), nullable=True), sa.Column('last_synced_at', sa.DateTime(timezone=True), nullable=True), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_table_metadata')) ) op.create_index(op.f('ix_table_metadata_id'), 'table_metadata', ['id'], unique=False) op.create_index(op.f('ix_table_metadata_table_name'), 'table_metadata', ['table_name'], unique=False) op.create_table('users', sa.Column('username', sa.String(length=50), nullable=False), sa.Column('email', sa.String(length=100), nullable=False), sa.Column('hashed_password', sa.String(length=255), nullable=False), sa.Column('full_name', sa.String(length=100), nullable=True), sa.Column('is_active', sa.Boolean(), nullable=False), sa.Column('avatar_url', sa.String(length=255), nullable=True), sa.Column('bio', sa.Text(), nullable=True), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.PrimaryKeyConstraint('id', name=op.f('pk_users')) ) op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True) op.create_index(op.f('ix_users_id'), 'users', ['id'], unique=False) op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True) op.create_table('user_roles', sa.Column('user_id', sa.Integer(), nullable=False), sa.Column('role_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['role_id'], ['roles.id'], name=op.f('fk_user_roles_role_id_roles')), sa.ForeignKeyConstraint(['user_id'], ['users.id'], name=op.f('fk_user_roles_user_id_users')), sa.PrimaryKeyConstraint('user_id', 'role_id', name=op.f('pk_user_roles')) ) op.create_table('workflows', sa.Column('name', sa.String(length=100), nullable=False, comment='工作流名称'), sa.Column('description', sa.Text(), nullable=True, comment='工作流描述'), sa.Column('status', sa.Enum('DRAFT', 'PUBLISHED', 'ARCHIVED', name='workflowstatus'), nullable=False, comment='工作流状态'), sa.Column('is_active', sa.Boolean(), nullable=False, comment='是否激活'), sa.Column('definition', sa.JSON(), nullable=False, comment='工作流定义'), sa.Column('version', sa.String(length=20), nullable=False, comment='版本号'), sa.Column('owner_id', sa.Integer(), nullable=False, comment='所有者ID'), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.ForeignKeyConstraint(['owner_id'], ['users.id'], name=op.f('fk_workflows_owner_id_users')), sa.PrimaryKeyConstraint('id', name=op.f('pk_workflows')) ) op.create_index(op.f('ix_workflows_id'), 'workflows', ['id'], unique=False) op.create_table('workflow_executions', sa.Column('workflow_id', sa.Integer(), nullable=False, comment='工作流ID'), sa.Column('status', sa.Enum('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'CANCELLED', name='executionstatus'), nullable=False, comment='执行状态'), sa.Column('input_data', sa.JSON(), nullable=True, comment='输入数据'), sa.Column('output_data', sa.JSON(), nullable=True, comment='输出数据'), sa.Column('started_at', sa.String(length=50), nullable=True, comment='开始时间'), sa.Column('completed_at', sa.String(length=50), nullable=True, comment='完成时间'), sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'), sa.Column('executor_id', sa.Integer(), nullable=False, comment='执行者ID'), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.ForeignKeyConstraint(['executor_id'], ['users.id'], name=op.f('fk_workflow_executions_executor_id_users')), sa.ForeignKeyConstraint(['workflow_id'], ['workflows.id'], name=op.f('fk_workflow_executions_workflow_id_workflows')), sa.PrimaryKeyConstraint('id', name=op.f('pk_workflow_executions')) ) op.create_index(op.f('ix_workflow_executions_id'), 'workflow_executions', ['id'], unique=False) op.create_table('node_executions', sa.Column('workflow_execution_id', sa.Integer(), nullable=False, comment='工作流执行ID'), sa.Column('node_id', sa.String(length=50), nullable=False, comment='节点ID'), sa.Column('node_type', sa.Enum('START', 'END', 'LLM', 'CONDITION', 'LOOP', 'CODE', 'HTTP', 'TOOL', name='nodetype'), nullable=False, comment='节点类型'), sa.Column('node_name', sa.String(length=100), nullable=False, comment='节点名称'), sa.Column('status', sa.Enum('PENDING', 'RUNNING', 'COMPLETED', 'FAILED', 'CANCELLED', name='executionstatus'), nullable=False, comment='执行状态'), sa.Column('input_data', sa.JSON(), nullable=True, comment='输入数据'), sa.Column('output_data', sa.JSON(), nullable=True, comment='输出数据'), sa.Column('started_at', sa.String(length=50), nullable=True, comment='开始时间'), sa.Column('completed_at', sa.String(length=50), nullable=True, comment='完成时间'), sa.Column('duration_ms', sa.Integer(), nullable=True, comment='执行时长(毫秒)'), sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'), sa.Column('id', sa.Integer(), nullable=False), sa.Column('created_at', sa.DateTime(), nullable=False), sa.Column('updated_at', sa.DateTime(), nullable=False), sa.Column('created_by', sa.Integer(), nullable=True), sa.Column('updated_by', sa.Integer(), nullable=True), sa.ForeignKeyConstraint(['workflow_execution_id'], ['workflow_executions.id'], name=op.f('fk_node_executions_workflow_execution_id_workflow_executions')), sa.PrimaryKeyConstraint('id', name=op.f('pk_node_executions')) ) op.create_index(op.f('ix_node_executions_id'), 'node_executions', ['id'], unique=False) # ### end Alembic commands ### def downgrade() -> None: """Downgrade schema.""" # ### commands auto generated by Alembic - please adjust! ### op.drop_index(op.f('ix_node_executions_id'), table_name='node_executions') op.drop_table('node_executions') op.drop_index(op.f('ix_workflow_executions_id'), table_name='workflow_executions') op.drop_table('workflow_executions') op.drop_index(op.f('ix_workflows_id'), table_name='workflows') op.drop_table('workflows') op.drop_table('user_roles') op.drop_index(op.f('ix_users_username'), table_name='users') op.drop_index(op.f('ix_users_id'), table_name='users') op.drop_index(op.f('ix_users_email'), table_name='users') op.drop_table('users') op.drop_index(op.f('ix_table_metadata_table_name'), table_name='table_metadata') op.drop_index(op.f('ix_table_metadata_id'), table_name='table_metadata') op.drop_table('table_metadata') op.drop_index(op.f('ix_roles_name'), table_name='roles') op.drop_index(op.f('ix_roles_id'), table_name='roles') op.drop_index(op.f('ix_roles_code'), table_name='roles') op.drop_table('roles') op.drop_index(op.f('ix_messages_id'), table_name='messages') op.drop_table('messages') op.drop_index(op.f('ix_llm_configs_provider'), table_name='llm_configs') op.drop_index(op.f('ix_llm_configs_name'), table_name='llm_configs') op.drop_index(op.f('ix_llm_configs_id'), table_name='llm_configs') op.drop_table('llm_configs') op.drop_index(op.f('ix_knowledge_bases_name'), table_name='knowledge_bases') op.drop_index(op.f('ix_knowledge_bases_id'), table_name='knowledge_bases') op.drop_table('knowledge_bases') op.drop_index(op.f('ix_excel_files_id'), table_name='excel_files') op.drop_table('excel_files') op.drop_index(op.f('ix_documents_id'), table_name='documents') op.drop_table('documents') op.drop_index(op.f('ix_database_configs_id'), table_name='database_configs') op.drop_table('database_configs') op.drop_index(op.f('ix_conversations_id'), table_name='conversations') op.drop_table('conversations') op.drop_index(op.f('ix_agent_configs_name'), table_name='agent_configs') op.drop_index(op.f('ix_agent_configs_id'), table_name='agent_configs') op.drop_table('agent_configs') # ### end Alembic commands ###