* [add]修改迁移文件新建空白表结构 * Add installation guide and environment setup Added installation instructions and environment requirements for MemoryBear. * [delete]删除api,web的readme.md。只保留唯一readme.md * Fix database connection example in README Update database connection configuration example in README.
189 lines
12 KiB
Python
189 lines
12 KiB
Python
"""20251120202612
|
||
|
||
Revision ID: d00648d486ca
|
||
Revises: 9a887a617afb
|
||
Create Date: 2025-11-20 20:26:12.910101
|
||
|
||
"""
|
||
from typing import Sequence, Union
|
||
|
||
from alembic import op
|
||
import sqlalchemy as sa
|
||
from sqlalchemy.dialects import postgresql
|
||
|
||
# revision identifiers, used by Alembic.
|
||
revision: str = 'd00648d486ca'
|
||
down_revision: Union[str, None] = '9a887a617afb'
|
||
branch_labels: Union[str, Sequence[str], None] = None
|
||
depends_on: Union[str, Sequence[str], None] = None
|
||
|
||
|
||
def upgrade() -> None:
|
||
# ### commands auto generated by Alembic - please adjust! ###
|
||
op.create_table('data_config',
|
||
sa.Column('config_id', sa.Integer(), autoincrement=True, nullable=False, comment='配置ID'),
|
||
sa.Column('config_name', sa.String(), nullable=False, comment='配置名称'),
|
||
sa.Column('config_desc', sa.String(), nullable=True, comment='配置描述'),
|
||
sa.Column('group_id', sa.String(), nullable=True, comment='组ID'),
|
||
sa.Column('user_id', sa.String(), nullable=True, comment='用户ID'),
|
||
sa.Column('apply_id', sa.String(), nullable=True, comment='应用ID'),
|
||
sa.Column('id', sa.String(), nullable=True, comment='模型配置 UUID'),
|
||
sa.Column('enable_llm_dedup_blockwise', sa.Boolean(), nullable=True, comment='启用LLM决策去重'),
|
||
sa.Column('enable_llm_disambiguation', sa.Boolean(), nullable=True, comment='启用LLM决策消歧'),
|
||
sa.Column('deep_retrieval', sa.Boolean(), nullable=True, comment='深度检索开关'),
|
||
sa.Column('t_type_strict', sa.Float(), nullable=True, comment='类型严格阈值'),
|
||
sa.Column('t_name_strict', sa.Float(), nullable=True, comment='名称严格阈值'),
|
||
sa.Column('t_overall', sa.Float(), nullable=True, comment='综合阈值'),
|
||
sa.Column('state', sa.Boolean(), nullable=True, comment='配置使用状态'),
|
||
sa.Column('chunker_strategy', sa.String(), nullable=True, comment='分块策略'),
|
||
sa.Column('pruning_enabled', sa.Boolean(), nullable=True, comment='是否启动智能语义剪枝'),
|
||
sa.Column('pruning_scene', sa.String(), nullable=True, comment='智能剪枝场景:education/online_service/outbound'),
|
||
sa.Column('pruning_threshold', sa.Float(), nullable=True, comment='智能语义剪枝阈值(0-0.9)'),
|
||
sa.Column('enable_self_reflexion', sa.Boolean(), nullable=True, comment='是否启用自我反思'),
|
||
sa.Column('iteration_period', sa.String(), nullable=True, comment='反思迭代周期'),
|
||
sa.Column('reflexion_range', sa.String(), nullable=True, comment='反思范围:部分/全部'),
|
||
sa.Column('baseline', sa.String(), nullable=True, comment='基线:时间/事实/时间和事实'),
|
||
sa.Column('statement_granularity', sa.Integer(), nullable=True, comment='陈述提取颗粒度,挡位 1/2/3'),
|
||
sa.Column('include_dialogue_context', sa.Boolean(), nullable=True, comment='是否包含对话上下文'),
|
||
sa.Column('max_context', sa.Integer(), nullable=True, comment='对话语境中包含字符的最大数量'),
|
||
sa.Column('λ_time', sa.Float(), nullable=True, comment='最低保持度,0-1 小数'),
|
||
sa.Column('λ_mem', sa.Float(), nullable=True, comment='遗忘率,0-1 小数'),
|
||
sa.Column('offset', sa.Float(), nullable=True, comment='偏移度,0-1 小数'),
|
||
sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'),
|
||
sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'),
|
||
sa.PrimaryKeyConstraint('config_id')
|
||
)
|
||
op.create_table('retrieval_info',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('host_id', sa.UUID(), nullable=False),
|
||
sa.Column('retrieve_info', sa.Text(), nullable=True),
|
||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||
sa.PrimaryKeyConstraint('id')
|
||
)
|
||
op.create_index(op.f('ix_retrieval_info_id'), 'retrieval_info', ['id'], unique=False)
|
||
op.create_table('end_users',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('app_id', sa.UUID(), nullable=False),
|
||
sa.Column('end_user_id', sa.UUID(), nullable=False),
|
||
sa.Column('other_id', sa.UUID(), nullable=False),
|
||
sa.Column('other_name', sa.String(), nullable=False),
|
||
sa.Column('other_address', sa.String(), nullable=False),
|
||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||
sa.ForeignKeyConstraint(['app_id'], ['apps.id'], ),
|
||
sa.PrimaryKeyConstraint('id')
|
||
)
|
||
op.create_index(op.f('ix_end_users_id'), 'end_users', ['id'], unique=False)
|
||
op.create_table('memory_increments',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('workspace_id', sa.UUID(), nullable=False),
|
||
sa.Column('total_num', sa.Integer(), nullable=False),
|
||
sa.Column('created_at', sa.Date(), nullable=True),
|
||
sa.Column('updated_at', sa.Date(), nullable=True),
|
||
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ),
|
||
sa.PrimaryKeyConstraint('id')
|
||
)
|
||
op.create_index(op.f('ix_memory_increments_id'), 'memory_increments', ['id'], unique=False)
|
||
op.create_index(op.f('ix_memory_increments_workspace_id'), 'memory_increments', ['workspace_id'], unique=False)
|
||
op.create_table('api_keys',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('name', sa.String(length=255), nullable=False, comment='API Key 名称'),
|
||
sa.Column('description', sa.Text(), nullable=True, comment='描述'),
|
||
sa.Column('key_prefix', sa.String(length=20), nullable=False, comment='Key 前缀'),
|
||
sa.Column('key_hash', sa.String(length=255), nullable=False, comment='Key 哈希值'),
|
||
sa.Column('type', sa.String(length=50), nullable=False, comment='API Key 类型'),
|
||
sa.Column('scopes', postgresql.JSONB(astext_type=sa.Text()), nullable=False, comment='权限范围列表'),
|
||
sa.Column('workspace_id', sa.UUID(), nullable=False, comment='所属工作空间'),
|
||
sa.Column('resource_id', sa.UUID(), nullable=True, comment='关联资源ID'),
|
||
sa.Column('resource_type', sa.String(length=50), nullable=True, comment='资源类型'),
|
||
sa.Column('rate_limit', sa.Integer(), nullable=True, comment='速率限制(请求/分钟)'),
|
||
sa.Column('quota_limit', sa.Integer(), nullable=True, comment='配额限制(总请求数)'),
|
||
sa.Column('quota_used', sa.Integer(), nullable=True, comment='已使用配额'),
|
||
sa.Column('expires_at', sa.DateTime(), nullable=True, comment='过期时间'),
|
||
sa.Column('is_active', sa.Boolean(), nullable=False, comment='是否激活'),
|
||
sa.Column('last_used_at', sa.DateTime(), nullable=True, comment='最后使用时间'),
|
||
sa.Column('usage_count', sa.Integer(), nullable=True, comment='使用次数'),
|
||
sa.Column('created_by', sa.UUID(), nullable=False, comment='创建者'),
|
||
sa.Column('created_at', sa.DateTime(), nullable=False, comment='创建时间'),
|
||
sa.Column('updated_at', sa.DateTime(), nullable=False, comment='更新时间'),
|
||
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
||
sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ondelete='CASCADE'),
|
||
sa.PrimaryKeyConstraint('id')
|
||
)
|
||
op.create_index(op.f('ix_api_keys_id'), 'api_keys', ['id'], unique=False)
|
||
op.create_index(op.f('ix_api_keys_key_hash'), 'api_keys', ['key_hash'], unique=True)
|
||
op.create_index(op.f('ix_api_keys_resource_id'), 'api_keys', ['resource_id'], unique=False)
|
||
op.create_index(op.f('ix_api_keys_type'), 'api_keys', ['type'], unique=False)
|
||
op.create_index(op.f('ix_api_keys_workspace_id'), 'api_keys', ['workspace_id'], unique=False)
|
||
op.create_table('release_shares',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('release_id', sa.UUID(), nullable=False),
|
||
sa.Column('app_id', sa.UUID(), nullable=False),
|
||
sa.Column('is_enabled', sa.Boolean(), nullable=False, comment='是否启用公开分享'),
|
||
sa.Column('share_token', sa.String(), nullable=False, comment='公开访问的唯一标识'),
|
||
sa.Column('require_password', sa.Boolean(), nullable=False, comment='是否需要密码访问'),
|
||
sa.Column('password_hash', sa.String(), nullable=True, comment='访问密码哈希'),
|
||
sa.Column('allow_embed', sa.Boolean(), nullable=False, comment='是否允许嵌入'),
|
||
sa.Column('embed_domains', postgresql.JSON(astext_type=sa.Text()), nullable=True, comment='允许嵌入的域名白名单'),
|
||
sa.Column('view_count', sa.Integer(), nullable=False, comment='访问次数'),
|
||
sa.Column('last_accessed_at', sa.DateTime(), nullable=True, comment='最后访问时间'),
|
||
sa.Column('created_by', sa.UUID(), nullable=False, comment='创建者'),
|
||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||
sa.ForeignKeyConstraint(['app_id'], ['apps.id'], ondelete='CASCADE'),
|
||
sa.ForeignKeyConstraint(['created_by'], ['users.id'], ),
|
||
sa.ForeignKeyConstraint(['release_id'], ['app_releases.id'], ondelete='CASCADE'),
|
||
sa.PrimaryKeyConstraint('id'),
|
||
sa.UniqueConstraint('release_id', name='uq_release_share_release_id')
|
||
)
|
||
op.create_index(op.f('ix_release_shares_app_id'), 'release_shares', ['app_id'], unique=False)
|
||
op.create_index(op.f('ix_release_shares_id'), 'release_shares', ['id'], unique=False)
|
||
op.create_index(op.f('ix_release_shares_release_id'), 'release_shares', ['release_id'], unique=True)
|
||
op.create_index(op.f('ix_release_shares_share_token'), 'release_shares', ['share_token'], unique=True)
|
||
op.create_table('api_key_logs',
|
||
sa.Column('id', sa.UUID(), nullable=False),
|
||
sa.Column('api_key_id', sa.UUID(), nullable=False, comment='API Key ID'),
|
||
sa.Column('endpoint', sa.String(length=255), nullable=False, comment='请求端点'),
|
||
sa.Column('method', sa.String(length=10), nullable=False, comment='HTTP 方法'),
|
||
sa.Column('ip_address', sa.String(length=50), nullable=True, comment='IP 地址'),
|
||
sa.Column('user_agent', sa.Text(), nullable=True, comment='User Agent'),
|
||
sa.Column('status_code', sa.Integer(), nullable=True, comment='响应状态码'),
|
||
sa.Column('response_time', sa.Integer(), nullable=True, comment='响应时间(毫秒)'),
|
||
sa.Column('tokens_used', sa.Integer(), nullable=True, comment='使用的 Token 数'),
|
||
sa.Column('created_at', sa.DateTime(), nullable=False, comment='创建时间'),
|
||
sa.ForeignKeyConstraint(['api_key_id'], ['api_keys.id'], ondelete='CASCADE'),
|
||
sa.PrimaryKeyConstraint('id')
|
||
)
|
||
op.create_index(op.f('ix_api_key_logs_api_key_id'), 'api_key_logs', ['api_key_id'], unique=False)
|
||
op.create_index(op.f('ix_api_key_logs_created_at'), 'api_key_logs', ['created_at'], unique=False)
|
||
op.create_index(op.f('ix_api_key_logs_id'), 'api_key_logs', ['id'], unique=False)
|
||
# ### end Alembic commands ###
|
||
|
||
|
||
def downgrade() -> None:
|
||
# ### commands auto generated by Alembic - please adjust! ###
|
||
op.drop_index(op.f('ix_api_key_logs_id'), table_name='api_key_logs')
|
||
op.drop_index(op.f('ix_api_key_logs_created_at'), table_name='api_key_logs')
|
||
op.drop_index(op.f('ix_api_key_logs_api_key_id'), table_name='api_key_logs')
|
||
op.drop_table('api_key_logs')
|
||
op.drop_index(op.f('ix_release_shares_share_token'), table_name='release_shares')
|
||
op.drop_index(op.f('ix_release_shares_release_id'), table_name='release_shares')
|
||
op.drop_index(op.f('ix_release_shares_id'), table_name='release_shares')
|
||
op.drop_index(op.f('ix_release_shares_app_id'), table_name='release_shares')
|
||
op.drop_table('release_shares')
|
||
op.drop_index(op.f('ix_api_keys_workspace_id'), table_name='api_keys')
|
||
op.drop_index(op.f('ix_api_keys_type'), table_name='api_keys')
|
||
op.drop_index(op.f('ix_api_keys_resource_id'), table_name='api_keys')
|
||
op.drop_index(op.f('ix_api_keys_key_hash'), table_name='api_keys')
|
||
op.drop_index(op.f('ix_api_keys_id'), table_name='api_keys')
|
||
op.drop_table('api_keys')
|
||
op.drop_index(op.f('ix_memory_increments_workspace_id'), table_name='memory_increments')
|
||
op.drop_index(op.f('ix_memory_increments_id'), table_name='memory_increments')
|
||
op.drop_table('memory_increments')
|
||
op.drop_index(op.f('ix_end_users_id'), table_name='end_users')
|
||
op.drop_table('end_users')
|
||
op.drop_index(op.f('ix_retrieval_info_id'), table_name='retrieval_info')
|
||
op.drop_table('retrieval_info')
|
||
op.execute('DROP TABLE IF EXISTS data_config')
|
||
# ### end Alembic commands ###
|