"""只读比对:pms_dev 与 pms 的目标列定义 + organizations.parent_id 索引/外键 用法: python .tmp-schema-align/compare.py 只发 SELECT,不做任何写入。 """ import pymysql COLS = [ ("charge_records", "energy"), ("charge_records", "start_time"), ("charge_records", "end_time"), ("energy_stats", "total_energy"), ("download_tasks", "completed_at"), ("organizations", "parent_id"), ] COL_SQL = """ SELECT COLUMN_TYPE, IS_NULLABLE, IFNULL(CAST(COLUMN_DEFAULT AS CHAR),''), IFNULL(CAST(COLUMN_COMMENT AS CHAR),'') FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=%s AND TABLE_NAME=%s AND COLUMN_NAME=%s """ IDX_SQL = """ SELECT INDEX_NAME, SEQ_IN_INDEX, COLUMN_NAME, NON_UNIQUE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA=%s AND TABLE_NAME='organizations' ORDER BY INDEX_NAME, SEQ_IN_INDEX """ FK_SQL = """ SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=%s AND TABLE_NAME='organizations' AND REFERENCED_TABLE_NAME IS NOT NULL """ def snapshot(db): c = pymysql.connect(host="10.8.0.252", user="root", password="Hbhyg731024@", database=db) cur = c.cursor() cols = {} for t, col in COLS: cur.execute(COL_SQL, (db, t, col)) cols[f"{t}.{col}"] = cur.fetchone() or ("",) * 4 cur.execute(IDX_SQL, (db,)) idx = cur.fetchall() cur.execute(FK_SQL, (db,)) fk = cur.fetchall() c.close() return cols, idx, fk dev_cols, dev_idx, dev_fk = snapshot("pms_dev") prd_cols, prd_idx, prd_fk = snapshot("pms") print("=" * 100) print("%-32s | %-44s | %-44s | %s" % ("列", "pms_dev(测试)", "pms(生产)", "一致")) print("=" * 100) all_same = True for key in [f"{t}.{c}" for t, c in COLS]: d, p = dev_cols[key], prd_cols[key] same = d == p all_same &= same fmt = lambda r: "%s null=%s def=%s cmt=%s" % r print("%-32s | %-44s | %-44s | %s" % (key, fmt(d), fmt(p), "OK" if same else "DIFF")) print("-" * 100) print("列定义完全一致:", all_same) print() print("organizations 索引 pms_dev :", dev_idx) print("organizations 索引 pms :", prd_idx) print("parent_id 处于索引最左列 :", any(r[1] == 1 and r[2] == "parent_id" for r in dev_idx), "/", any(r[1] == 1 and r[2] == "parent_id" for r in prd_idx)) print() print("organizations 自引用外键 pms_dev :", dev_fk) print("organizations 自引用外键 pms :", prd_fk) print("外键均存在:", bool(dev_fk) and bool(prd_fk))