"""2026070902_add_generated_date_expression_indexes Revision ID: 2026070902 Revises: 2026070901 Create Date: 2026-07-09 00:00:00.000000 该文件包含 2026-07-09 的数据库迁移内容: 1. chat_generation_tasks 表增加 generated_at 日期表达式索引,优化按日期分组/筛选 2. generation_records 表增加 generated_at 日期表达式索引,优化按日期分组/筛选 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa revision: str = '2026070902' down_revision: Union[str, None] = '2026070901' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ======================================== # 2026-07-09 - 生成记录表增加日期表达式索引 # ======================================== # 使用 CAST(timezone('utc', generated_at) AS date) 而不是 date(generated_at): # 1) 当 generated_at 为 timestamptz 时,date() 的结果依赖会话时区,属于 STABLE 函数, # 无法用于索引表达式。显式指定 UTC 时区后转为 date 是纯计算,属于 IMMUTABLE。 # 2) 必须用 CAST(... AS date) 而不能用 ::date::: 的优先级高于函数调用, # PG 会把 func(x)::date 解析为 func(x::date),导致语法错误。 op.create_index( 'idx_chat_generation_tasks_generated_date', 'chat_generation_tasks', [sa.text("CAST(timezone('utc', generated_at) AS date)")], unique=False, ) op.create_index( 'idx_generation_records_generated_date', 'generation_records', [sa.text("CAST(timezone('utc', generated_at) AS date)")], unique=False, ) def downgrade() -> None: # ======================================== # 2026-07-09 - 生成记录表增加日期表达式索引(回滚) # ======================================== op.drop_index('idx_generation_records_generated_date', table_name='generation_records') op.drop_index('idx_chat_generation_tasks_generated_date', table_name='chat_generation_tasks')