Files
life-echo/api/alembic/versions/0001_initial_schema.py
2026-05-19 16:40:45 +08:00

83 lines
3.0 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.
"""initial schema (squashed)
单一迁移pgvector + 当前全部 ORM 表(含 conversations.deleted_at 软删除);并补充 models 未声明的
story_image_intents.asset_id → assets 外键,以及每个 story 仅一条 primary intent 的唯一索引。
chapters 含 story 物化字段markdown_compose_dirty、markdown_composed_at、reading_segments_json
(阅读片段快照,随 ORM 一并 create_all
已并入原 0002stories-first无 chapter_sections / memoir_images.section_id与原 0003segments.tts_audio_urls
的语义:仅对「全新库」由 create_all 建出;**已有库不会 ALTER**。
老库缺列见 0019_align_legacy_schemasegments.audio_duration_seconds、tts_audio_urls
conversations.deleted_atconversation_messages.tts_audio_urls 等)。
conversation_messages 表由 ORM 在 0001 create_all 中创建(新库);老库若缺表须单独处理。
story_image_intents 无 source_span主图回填在正文末尾意图仅存 caption / prompt_brief 等)。
新库 / 删库重来:`alembic upgrade head`。
Revision ID: 0001_initial
Revises:
"""
from typing import Sequence, Union
from alembic import op
from sqlalchemy import text
revision: str = "0001_initial"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def _import_all_models() -> None:
from app.features.asset import models as _asset_models # noqa: F401
from app.features.auth import models as _auth_models # noqa: F401
from app.features.conversation import models as _conv_models # noqa: F401
from app.features.memory import models as _memory_models # noqa: F401
from app.features.memoir import models as _memoir_models # noqa: F401
from app.features.payment import models as _payment_models # noqa: F401
from app.features.story import models as _story_models # noqa: F401
from app.features.user import models as _user_models # noqa: F401
def upgrade() -> None:
conn = op.get_bind()
conn.execute(text("CREATE EXTENSION IF NOT EXISTS vector"))
from app.core.db import Base
_import_all_models()
Base.metadata.create_all(bind=conn)
op.create_foreign_key(
"fk_story_image_intents_asset_id_assets",
"story_image_intents",
"assets",
["asset_id"],
["id"],
ondelete="SET NULL",
)
op.execute(
"""
CREATE UNIQUE INDEX IF NOT EXISTS uq_story_primary_image_intent
ON story_image_intents (story_id)
WHERE intent_role = 'primary'
"""
)
def downgrade() -> None:
conn = op.get_bind()
from app.core.db import Base
op.execute("DROP INDEX IF EXISTS uq_story_primary_image_intent")
op.drop_constraint(
"fk_story_image_intents_asset_id_assets",
"story_image_intents",
type_="foreignkey",
)
_import_all_models()
Base.metadata.drop_all(bind=conn)
conn.execute(text("DROP EXTENSION IF EXISTS vector"))