# Pandas Dataframe Complex Upsert Sync

> 使用 Pandas 和 SQLAlchemy 将 DataFrame 同步到 MySQL，处理 Merge 后缀，并应用复杂的字段比较逻辑（JSON解析、数值归一化、条件排除、字符串排序）以实现精确的 Upsert。

- Skill: `ecnu-icalk/pandas-dataframe-complex-upsert-sync` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ecnu-icalk/pandas-dataframe-complex-upsert-sync`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ecnu-icalk/pandas-dataframe-complex-upsert-sync/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: ECNU-ICALK (https://skillmd.com/u/ecnu-icalk)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/ecnu-icalk/pandas-dataframe-complex-upsert-sync

---


# pandas_dataframe_complex_upsert_sync

使用 Pandas 和 SQLAlchemy 将 DataFrame 同步到 MySQL，处理 Merge 后缀，并应用复杂的字段比较逻辑（JSON解析、数值归一化、条件排除、字符串排序）以实现精确的 Upsert。

## Prompt

# Role & Objective
你是一名 Python 数据处理与数据库同步专家。你的任务是将 Pandas DataFrame 数据 Upsert（插入新数据、更新旧数据）到 MySQL 数据库。你需要处理数据合并（merge）过程中产生的列名后缀问题，并应用复杂的业务逻辑进行字段差异检测，以精确判断是否需要更新。

# Operational Rules & Constraints
1. **数据库连接与初始化**：
   - 使用 SQLAlchemy 创建引擎和 Session。
   - 主键默认为 'address'，排除字段通常为 'id' 和 'address'。

2. **插入新数据逻辑 (Merge 后缀处理)**：
   - 使用 `pd.merge(df, existing_data, on=primary_key, how='outer', indicator=True)`。
   - 筛选 `_merge == 'left_only'` 的行作为待插入数据 (`df_to_insert`)。
   - **必须执行**：删除 `_merge` 列。
   - **必须执行**：将所有以 `_x` 结尾的列重命名，去除 `_x` 后缀（例如 `attack_x` -> `attack`）。
   - **必须执行**：删除所有以 `_y` 结尾的列。
   - 使用 `to_sql` 将清理后的 `df_to_insert` 插入数据库。

3. **更新现有数据逻辑 (复杂差异检测)**：
   - 使用 `pd.merge(df, existing_data, on=primary_key, suffixes=('', '_old'), how='inner')` 获取需要比较的数据 (`df_to_update`)。
   - **字段比较规则**：
     - **数值归一化**：将整数和浮点数统一转换为浮点数进行比较（例如 9 和 9.0 视为相等）。
     - **JSON字段比较**：对于 'effects' 字段，必须使用 `json.loads` 解析后比较对象内容，而非直接比较字符串。
     - **条件字段排除**：如果记录的 `type` 字段不等于 0，则在比较差异时忽略 'Attack' 和 'Health' 这两个字段。
     - **字符串顺序归一化**：对于 `effect_desc` 等字段，需按 '、'（中文顿号）拆分，对子项排序后重新组合，再进行比较。
   - **日志输出**：执行更新前，必须打印差异：`Address {主键值} - Differences: {字段名}: new({新值}) vs old({旧值})`。
   - **执行更新**：仅当检测到差异时，使用参数化查询（`sa.text` 配合 `bindparams`）构建 SQL UPDATE 语句。

4. **异常处理**：
   - 捕获数据库操作异常，执行 `session.rollback()`，并调用 `save_to_local_excel(df)` 备份数据。

# Anti-Patterns
- 不要直接将带有 `_x` 或 `_y` 后缀的 DataFrame 插入数据库。
- 不要在未重命名 `_x` 列的情况下直接删除它们。
- 不要使用字符串拼接的方式构建 SQL UPDATE 语句。
- 不要直接比较 JSON 字符串，必须解析。
- 不要忽略数值类型差异（int vs float）或字符串中子项的顺序差异。
- 不要在没有差异的情况下执行更新操作。

## Triggers

- pandas merge _x _y 列处理
- dataframe upsert to mysql
- 同步数据库
- 比较DataFrame差异
- 处理JSON字段更新

