一、需求

现在需要准备大量的测试数据,手工在页面创建工作量巨大;数据均存放在MySQL数据库中,为了尽可能模拟真实的情况,准备使用Python将生产环境的数据复制到测试环境。

二、准备

Python连接MySQL数据库使用pymysql库

pip install pymysql

三、步骤

查询获取结果

从生产环境MySQL表中查询要复制的数据,连接数据库执行查询语句获取结果

# 【查询获取结果】
db1_info = {'host': "192.168.1.1", 'port': 3306, 'user': "test", 'passwd': "test", 'db': "test_db",
            'charset': "utf8"}  # 数据库1连接信息
sql_select = "select * from question_item where form_ident=5********0;"  # 查询SQL语句
table_name_li = re.findall('from (.*) where', sql_select.lower())  # 提取表名
conn = pymysql.connect(**db1_info)  # 连接数据库1
cursor = conn.cursor(cursor=cursors.DictCursor)  # 数据库1的游标
cursor.execute(sql_select)  # 执行SQL
datas = cursor.fetchall()  # 获取SQL查询结果
conn.close()  # 关闭数据库1连接
pprint(datas)  # 打印查询结果

运行结果:

Python实现MySQL数据迁移_Python

组装插入SQL语句

遍历查询结果,根据结果拼接插入SQL语句

# 【组装插入SQL语句】
for idx, val in enumerate(datas):  # 遍历查询结果
    table_name = table_name_li[0]  # 表名
    fields = str(tuple([k for k in val if k != 'id'])).replace("'", '')  # 提取表字段,排除id,先转换为元祖再转换为字符串并替换单引号'
    # 提取表字段的的值并根据mysql中不同数据类型分别处理(bit、datetime、null、其他)
    values = []
    for k in val:  # 遍历值--字典
        if k != 'id':  # 排除id
            if isinstance(val[k], bytes):  # bit类型
                values.append(ord(val[k]))
            elif isinstance(val[k], datetime.datetime):  # datetime类型
                values.append(f"'^{val[k].strftime('%Y-%m-%d %H:%M:%S.%f')}^'")  # 在首尾添加处理符号'^ ^'
            elif val[k] is None:  # null
                values.append('^null^')  # 在首尾添加处理符号'^ ^'
            else:  # 其他
                values.append(val[k])
    values = str(tuple(values)).replace("'^", '')  # 先转换为元祖再转换为字符串并替换处理符号'^
    values = values.replace("^'", '')  # 替换处理符号^'
    sql_insert = f"INSERT INTO {table_name} {fields} VALUES {values}; "  # 组装插入SQL语句
    print(sql_insert)

运行结果:

Python实现MySQL数据迁移_MySQL_02

执行插入SQL语句

连接测试环境数据库,执行组装好的插入SQL语句

# 【执行插入SQL语句】
db2_info = {'host': "192.168.1.2", 'port': 3306, 'user': "test", 'passwd': "test",
            'db': "test_db_2", 'charset': "utf8"}  # 数据库2连接信息
conn = pymysql.connect(**db2_info)  # 连接数据库2
cursor = conn.cursor()  # 数据库2的游标
cursor.execute(sql_insert)  # 执行插入SQL
conn.commit()  # 提交插入
conn.close()  # 关闭数据库1连接