Files
MemoryBear/api/migrations/versions/d00648d486ca_20251120202612.py
lanceyq 570392aa6f Docs/installation tutorial (#7)
* [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.
2025-12-05 21:38:31 +08:00

189 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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 ###