You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跨两台服务器的四张数据库表迁移合并脚本开发需求

跨服务器数据库表迁移(合并)脚本开发指南

刚入职就碰到跨库跨服务器的表合并需求?我之前处理过几乎一模一样的场景,给你整理一套实用的脚本开发思路和示例,帮你快速落地:

一、列完全匹配的Table A → Table A2 迁移

这部分是最省心的,因为结构完全一致,核心就是处理重复数据(毕竟是合并,不是覆盖):

  • 核心思路:先获取目标表已有的主键数据,筛选源表中目标表没有的记录,再批量插入。如果需要更新已有数据,优先用INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或ON CONFLICT DO UPDATE(PostgreSQL),避免直接删除数据导致丢失。
  • Python脚本示例(通用型强,支持多种数据库):
    我常用Python+SQLAlchemy+pandas来做这种操作,代码可读性高,适配MySQL、PostgreSQL、SQL Server都没问题:
    from sqlalchemy import create_engine
    import pandas as pd
    import logging
    
    # 配置日志,方便排查问题
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    # 源/目标数据库连接字符串(根据你的数据库类型调整)
    source_db_url = 'mysql+pymysql://用户名:密码@源服务器IP:端口/源数据库名'
    target_db_url = 'mysql+pymysql://用户名:密码@目标服务器IP:端口/目标数据库名'
    
    # 创建数据库连接引擎
    source_engine = create_engine(source_db_url)
    target_engine = create_engine(target_db_url)
    
    try:
        # 读取源表数据
        source_a_data = pd.read_sql_table('TableA', source_engine)
        logger.info(f"成功读取源表TableA的{len(source_a_data)}条数据")
    
        # 获取目标表已有的主键(假设主键是id,根据实际调整)
        target_a_ids = pd.read_sql("SELECT id FROM TableA2", target_engine)['id'].tolist()
    
        # 筛选目标表没有的新数据
        new_data = source_a_data[~source_a_data['id'].isin(target_a_ids)]
    
        if not new_data.empty:
            # 批量插入目标表
            new_data.to_sql('TableA2', target_engine, if_exists='append', index=False)
            logger.info(f"成功向TableA2插入{len(new_data)}条新数据")
        else:
            logger.info("TableA没有新数据需要迁移")
    except Exception as e:
        logger.error(f"处理TableA迁移时出错:{str(e)}")
    
  • 备选方案(数据库原生工具):如果不想写代码,用数据库自带工具更快。比如MySQL可以用mysqldump导出源表,再用mysql命令导入,加上--insert-ignore跳过重复数据:
    # 导出源TableA
    mysqldump -h 源服务器IP -u 用户名 -p 源数据库名 TableA > table_a.sql
    # 导入到目标TableA2(跳过重复主键)
    mysql -h 目标服务器IP -u 用户名 -p 目标数据库名 --local-infile=1 -e "INSERT IGNORE INTO TableA2 SELECT * FROM TableA;"
    

二、列部分相似的Table B → Table B2 迁移

这部分需要先理清楚列的映射关系,是关键步骤:

  1. 先梳理列映射表:把两张表的列一一对应,标记出需要转换、设置默认值或者丢弃的列,比如:

    源Table B列目标Table B2列处理逻辑
    user_idid主键,用于去重
    real_namefull_name直接映射
    register_datejoin_time时间格式转换(比如字符串转datetime)
    -account_status设置默认值1(正常状态)
    unused_col-丢弃该列
  2. Python脚本示例:基于上面的映射表,做列转换和数据插入:

try:
# 读取源表TableB数据
source_b_data = pd.read_sql_table('TableB', source_engine)
logger.info(f"成功读取源表TableB的{len(source_b_data)}条数据")

# 获取目标表已有的主键
  target_b_ids = pd.read_sql("SELECT id FROM TableB2", target_engine)['id'].tolist()
  # 筛选新数据
  new_data_b = source_b_data[~source_b_data['user_id'].isin(target_b_ids)]

  if not new_data_b.empty:
      # 1. 列重命名(映射)
      new_data_b = new_data_b.rename(columns={
          'user_id': 'id',
          'real_name': 'full_name',
          'register_date': 'join_time'
      })
      # 2. 添加目标表需要的新列,设置默认值
      new_data_b['account_status'] = 1
      # 3. 时间格式转换(如果需要)
      new_data_b['join_time'] = pd.to_datetime(new_data_b['join_time'], format='%Y-%m-%d')
      # 4. 丢弃不需要的列
      new_data_b = new_data_b.drop(columns=['unused_col'])

      # 插入目标表
      new_data_b.to_sql('TableB2', target_engine, if_exists='append', index=False)
      logger.info(f"成功向TableB2插入{len(new_data_b)}条新数据")
  else:
      logger.info("TableB没有新数据需要迁移")

except Exception as e:
logger.error(f"处理TableB迁移时出错:{str(e)}")

3. **关键注意事项**:
 - 一定要先拿**小批量测试数据**跑一遍,验证列转换、默认值设置是否正确,避免全量插入出错
 - 如果有复杂的业务逻辑(比如源端的枚举值要转成目标端的另一个),可以用`map`函数处理:
   ```python
   status_map = {'active': 1, 'inactive': 0}
   new_data_b['account_status'] = new_data_b['source_status'].map(status_map)
   ```

## 三、脚本优化建议
- **增量迁移**:如果后续需要定期同步,不要每次全量读取,而是基于时间戳(比如`WHERE update_time > 上次同步时间`)或者自增主键做增量查询,大幅提高效率
- **事务处理**:如果是多表迁移,开启数据库事务,确保要么全部成功,要么回滚,避免数据不一致
- **日志完善**:把日志输出到文件,方便后续排查问题,比如添加`fileHandler`到logging配置

内容的提问来源于stack exchange,提问作者Black-Prince
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:01:30