"""添加指标模板表 Revision ID: 002_template Revises: initial Create Date: 2024-01-02 00:00:00.000000 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa # revision identifiers, used by Alembic. revision: str = '002_template' down_revision: Union[str, None] = 'initial' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # 创建指标模板表 op.create_table( 'indicator_templates', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('template_name', sa.String(length=200), nullable=False, comment='模板名称'), sa.Column('template_code', sa.String(length=50), nullable=False, comment='模板编码'), sa.Column('template_type', sa.String(length=30), nullable=False, comment='模板类型'), sa.Column('description', sa.Text(), nullable=True, comment='模板描述'), sa.Column('dimension_weights', sa.Text(), nullable=True, comment='维度权重 (JSON)'), sa.Column('assessment_cycle', sa.String(length=20), nullable=True, comment='考核周期'), sa.Column('is_active', sa.Boolean(), nullable=True, comment='是否启用'), sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'), sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('template_code') ) op.create_index('idx_template_type', 'indicator_templates', ['template_type']) op.create_index('idx_template_active', 'indicator_templates', ['is_active']) # 创建模板指标关联表 op.create_table( 'template_indicators', sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('template_id', sa.Integer(), nullable=False, comment='模板 ID'), sa.Column('indicator_id', sa.Integer(), nullable=False, comment='指标 ID'), sa.Column('category', sa.String(length=100), nullable=True, comment='指标分类'), sa.Column('target_value', sa.Numeric(precision=10, scale=2), nullable=True, comment='目标值'), sa.Column('target_unit', sa.String(length=50), nullable=True, comment='目标值单位'), sa.Column('weight', sa.Numeric(precision=5, scale=2), nullable=True, comment='权重'), sa.Column('scoring_method', sa.String(length=50), nullable=True, comment='评分方法'), sa.Column('scoring_params', sa.Text(), nullable=True, comment='评分参数 (JSON)'), sa.Column('sort_order', sa.Integer(), nullable=True, comment='排序'), sa.Column('remark', sa.Text(), nullable=True, comment='备注'), sa.Column('created_at', sa.DateTime(), nullable=True, comment='创建时间'), sa.Column('updated_at', sa.DateTime(), nullable=True, comment='更新时间'), sa.ForeignKeyConstraint(['template_id'], ['indicator_templates.id']), sa.ForeignKeyConstraint(['indicator_id'], ['indicators.id']), sa.PrimaryKeyConstraint('id') ) op.create_index('idx_ti_template', 'template_indicators', ['template_id']) op.create_index('idx_ti_indicator', 'template_indicators', ['indicator_id']) op.create_index('idx_ti_unique', 'template_indicators', ['template_id', 'indicator_id'], unique=True) # 为指标表添加 BSC 维度字段(如果不存在) # 注意:在 PostgreSQL 中,如果字段已存在会报错,需要检查 conn = op.get_bind() inspector = sa.inspect(conn) columns = [col['name'] for col in inspector.get_columns('indicators')] if 'bs_dimension' not in columns: op.add_column('indicators', sa.Column('bs_dimension', sa.String(length=30), nullable=True, comment='平衡计分卡维度')) if 'target_unit' not in columns: op.add_column('indicators', sa.Column('target_unit', sa.String(length=50), nullable=True, comment='目标值单位')) if 'assessment_method' not in columns: op.add_column('indicators', sa.Column('assessment_method', sa.Text(), nullable=True, comment='考核方法')) if 'deduction_standard' not in columns: op.add_column('indicators', sa.Column('deduction_standard', sa.Text(), nullable=True, comment='扣分标准')) if 'data_source' not in columns: op.add_column('indicators', sa.Column('data_source', sa.String(length=100), nullable=True, comment='数据来源')) if 'applicable_dept_types' not in columns: op.add_column('indicators', sa.Column('applicable_dept_types', sa.Text(), nullable=True, comment='适用科室类型')) if 'is_veto' not in columns: op.add_column('indicators', sa.Column('is_veto', sa.Boolean(), nullable=True, default=False, comment='是否一票否决指标')) def downgrade() -> None: op.drop_table('template_indicators') op.drop_table('indicator_templates')