# -*- coding: utf-8 -*- """zentao_dev_2026 补本项目增量 DDL(只结构,不含数据): - zt_file.url / zt_meeting.url - zt_story 7 url 列 + code_review_status - zt_story_expand ai_participation_rate + acceptance_criteria - zt_perf_config / zt_doc_check 两新表(空表) 幂等:逐列/逐表查 information_schema,缺才加。 """ import io, sys, pymysql sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') conn = pymysql.connect(host='192.168.1.161', user='devgps', password='dev@2021GPS', database='zentao_dev_2026', charset='utf8mb4', autocommit=True) cur = conn.cursor() COLUMNS = [ ('zt_file', 'url', "VARCHAR(512) DEFAULT NULL COMMENT '附件访问链接' AFTER `pathname`"), ('zt_meeting', 'url', "VARCHAR(512) DEFAULT NULL COMMENT '会议纪要MD访问链接(最新一份)'"), ('zt_story', 'prd_url', "VARCHAR(512) DEFAULT NULL COMMENT 'PRD文档访问链接'"), ('zt_story', 'code_review_url', "VARCHAR(512) DEFAULT NULL COMMENT '代码审查报告访问链接'"), ('zt_story', 'work_log_url', "VARCHAR(512) DEFAULT NULL COMMENT '工作日志访问链接'"), ('zt_story', 'test_case_url', "VARCHAR(512) DEFAULT NULL COMMENT '测试用例访问链接'"), ('zt_story', 'test_report_download_url', "VARCHAR(512) DEFAULT NULL COMMENT '测试报告模版下载访问链接'"), ('zt_story', 'test_report_submit_url', "VARCHAR(512) DEFAULT NULL COMMENT '测试报告提交访问链接'"), ('zt_story', 'test_other_url', "VARCHAR(512) DEFAULT NULL COMMENT '其他测试文档访问链接'"), ('zt_story', 'code_review_status', "VARCHAR(16) DEFAULT NULL COMMENT '审查状态 pass/reject'"), ('zt_story_expand', 'ai_participation_rate', "VARCHAR(16) DEFAULT NULL COMMENT 'AI参与率(只存不算,口径待定)' AFTER `ai_efficiency_coefficient`"), ('zt_story_expand', 'acceptance_criteria', "MEDIUMTEXT DEFAULT NULL COMMENT 'AI框架验收指标(Given/When/Then,MD)' AFTER `test_person`"), ] added, skipped = [], [] for table, col, definition in COLUMNS: cur.execute("""SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='zentao_dev_2026' AND table_name=%s AND column_name=%s""", (table, col)) if cur.fetchone()[0] > 0: skipped.append(f'{table}.{col}') continue cur.execute(f'ALTER TABLE `{table}` ADD COLUMN `{col}` {definition}') added.append(f'{table}.{col}') TABLES = { 'zt_perf_config': """CREATE TABLE `zt_perf_config` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `role` VARCHAR(32) NOT NULL COMMENT '岗位编码', `item_key` VARCHAR(64) NOT NULL COMMENT '指标编码', `item_name` VARCHAR(128) NOT NULL COMMENT '指标名称', `weight` DECIMAL(4,2) NOT NULL DEFAULT 0.00 COMMENT '权重(0~1,加分项为0)', `rule_json` TEXT DEFAULT NULL COMMENT '规则参数JSON', `enabled` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用', `create_user` VARCHAR(64) DEFAULT NULL, `create_time` DATETIME DEFAULT NULL, `update_user` VARCHAR(64) DEFAULT NULL, `update_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_role_item` (`role`, `item_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='绩效指标规则配置表(三期)'""", 'zt_doc_check': """CREATE TABLE `zt_doc_check` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '主键', `story_id` INT NOT NULL COMMENT '研发需求ID', `month` VARCHAR(7) NOT NULL COMMENT '考核月份 yyyy-MM', `doc_type` VARCHAR(32) NOT NULL COMMENT '文档类型', `present` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否齐备', `detail` VARCHAR(512) DEFAULT NULL, `status` VARCHAR(16) NOT NULL DEFAULT 'pending' COMMENT '状态', `appeal_reason` VARCHAR(512) DEFAULT NULL, `appeal_result` VARCHAR(8) DEFAULT NULL, `resolve_remark` VARCHAR(512) DEFAULT NULL, `check_time` DATETIME DEFAULT NULL, `create_time` DATETIME DEFAULT NULL, `update_time` DATETIME DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_story_month_doc` (`story_id`, `month`, `doc_type`), KEY `idx_month` (`month`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='大型需求文档齐备核查快照(FR-014 三期)'""", } for table, ddl in TABLES.items(): cur.execute("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='zentao_dev_2026' AND table_name=%s", (table,)) if cur.fetchone()[0] > 0: skipped.append(f'表 {table}') continue cur.execute(ddl) added.append(f'表 {table}') print('已加:', added) print('已存在跳过:', skipped) # 验证 for t, c in [('zt_file', 'url'), ('zt_meeting', 'url'), ('zt_story', 'code_review_status'), ('zt_story', 'test_report_submit_url'), ('zt_story_expand', 'acceptance_criteria'), ('zt_story_expand', 'ai_participation_rate')]: cur.execute("""SELECT COUNT(*) FROM information_schema.columns WHERE table_schema='zentao_dev_2026' AND table_name=%s AND column_name=%s""", (t, c)) assert cur.fetchone()[0] == 1, f'{t}.{c} 缺失!' cur.execute("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='zentao_dev_2026' AND table_name IN ('zt_perf_config','zt_doc_check')") assert cur.fetchone()[0] == 2, '新表缺失!' print('验证通过:12 列 + 2 表全部就位(空表,无数据)')