happyhappy没有句号 2024-11-16 13:32 采纳率: 100%
浏览 9
已结题

pyodbc和pymssql同步数据怎么循环插入新数据,重复数据跳过

**怎么python实现读SQL Server表的数据插入MySQL,存在数据跳过呢,初学者,只会清空表格,全部重新插入,怎么将新的插入 **

import pyodbc
import pymysql
from datetime import datetime
import time

# SQL Server数据库连接配置信息
server = '127.0.0.1'
database = 'Dianhan'
username = 'sa'
password = '123456'

while True:
    try:
        # 建立与SQL Server数据库的连接,修正驱动部分
        conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=' + server + ';DATABASE=' + database + ';UID=' + username + ';PWD=' + password)

        # 连接MySQL数据库
        conn2 = pymysql.connect(host='127.0.0.1', user='root', password='123456', database='test', port=3306)

        # 获取SQL Server表的列名
        sql_server_cursor = conn.cursor()
        column_names_query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME ='weldmeasureprot_t'"
        sql_server_cursor.execute(column_names_query)
        column_names = [row[0] for row in sql_server_cursor.fetchall()]

        # 查询SQL Server表的所有数据
        sql_server_data_query = "SELECT * FROM Weldmeasureprot_T"
        sql_server_cursor.execute(sql_server_data_query)
        sql_server_data = sql_server_cursor.fetchall()

        # 构建插入到MySQL表的SQL语句,使用正确的表名
        placeholders = ', '.join(['%s'] * len(column_names))
        if not column_names:
            print("未能获取到有效的列名列表,请检查相关查询或数据库连接。")
            raise ValueError("列名列表为空,无法继续构建插入语句。")
        insert_query = "INSERT INTO weldMeasureProt_t ({}) VALUES ({})".format(', '.join(column_names), placeholders)
        # insert_query = "INSERT INTO weldMeasureProt_t ({}) VALUES ({})".format(', '.join(column_names), '%s')
        # placeholders = [''] * len(column_names)
        # 获取MySQL插入操作的游标
        mysql_cursor = conn2.cursor()
        # 插入前清空表
        mysql_cursor.execute("TRUNCATE TABLE weldMeasureProt_t ")
        # 遍历插入数据到MySQL表
        for row in sql_server_data:
            values = []
            for i, column in enumerate(column_names):
                values.append(row[i])
            mysql_cursor.execute(insert_query, tuple(values))  # values传入元祖
            print(values)
        print()
        # 提交MySQL插入操作,使数据生效
        conn2.commit()

        print("数据从SQL Server成功迁移到MySQL。%s"%datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

    except pyodbc.Error as e:
        print(f"连接或操作SQL Server数据库时出错: {e}")
    except pymysql.Error as e:
        print(f"连接或操作MySQL数据库时出错: {e}")
    finally:
        # 关闭SQL Server游标和连接
        if 'sql_server_cursor' in locals():
            sql_server_cursor.close()
        if 'conn' in locals():
            conn.close()

        # 关闭MySQL游标和连接
        if 'mysql_cursor' in locals():
            mysql_cursor.close()
        if 'conn2' in locals():
            conn2.close()

    time.sleep(10)

  • 写回答

1条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    从您的描述和代码来看,您正在尝试将SQL Server中的表数据同步到MySQL,同时希望在插入数据时跳过重复的记录。这可以通过在MySQL中使用主键或唯一索引来实现,或者在插入前检查数据是否已存在。以下是修改后的代码示例,以跳过重复数据:

    首先,确保MySQL表中有一个可以用于检查重复数据的字段,例如主键或具有唯一约束的字段。如果没有这样的字段,可能需要创建一个。然后,您可以使用以下步骤来插入数据并跳过重复项:

    1. 从SQL Server获取数据。
    2. 在插入到MySQL之前,检查数据是否已经存在。
    3. 如果数据不存在,则插入到MySQL中。

    以下是修改后的代码示例:

    import pyodbc
    import pymysql
    from datetime import datetime
    import time
    
    # 数据库连接配置信息保持不变...
    
    # 主循环不变...
    while True:
        try:
            # 建立SQL Server数据库连接不变...
            # 连接MySQL数据库不变...
            # 获取SQL Server表的列名不变...
            # 查询SQL Server表的所有数据不变...
            # 构建插入到MySQL表的SQL语句(假设存在一个唯一标识字段unique_id)
            insert_query = "INSERT IGNORE INTO weldMeasureProt_t (unique_id, ...) VALUES (%s, ...)" # 使用IGNORE关键字跳过重复数据插入错误
            # 获取MySQL插入操作的游标不变...
            # 遍历插入数据到MySQL表(增加检查数据是否已存在的逻辑)
            for row in sql_server_data:
                unique_value = row[unique_id_index]  # 获取唯一标识字段的值(假设unique_id是列索引)
                # 检查数据是否已经存在于MySQL表中(这里使用唯一标识字段作为检查条件)
                check_query = "SELECT COUNT(*) FROM weldMeasureProt_t WHERE unique_id = %s"  # 使用唯一标识字段作为条件查询是否已经存在记录
                mysql_cursor.execute(check_query, (unique_value,))  # 执行查询检查是否存在记录
                if mysql_cursor.fetchone()[0] == 0:  # 如果返回的记录数为0,表示不存在记录,则进行插入操作
                    mysql_cursor.execute(insert_query, tuple(values))  # values为从SQL Server获取的数据组成的元组(去掉唯一标识字段)
            print("数据同步完成。")  # 或其他提示信息
            # 提交MySQL插入操作不变...
        except Exception as e:  # 使用更广泛的异常捕获以便于调试和日志记录
            print(f"发生错误: {e}")  # 输出错误信息或其他日志记录方式
        finally:  # 关闭数据库连接和游标的逻辑不变...
        time.sleep(10)  # 休眠一段时间后再进行下一次同步(可选)
    

    请注意以下几点:

    • unique_id 是假设的用于检查重复数据的字段索引或名称。您需要替换为实际的唯一标识字段。如果没有这样的字段,则需要确定一种方法来检查重复的数据行。如果数据是唯一的并且没有主键或唯一索引字段,则可能需要检查整个行数据是否已存在。这会增加检查的复杂性并可能影响性能。在这种情况下,可能需要考虑其他策略来避免重复数据的插入问题。另外,“INSERT IGNORE INTO”命令可以帮助忽略因重复键引发的错误并继续执行插入操作。这对于确保只插入新记录非常有用。但是,请注意使用它时要小心,因为它也会忽略其他类型的错误(例如违反约束的错误)。因此在使用前确保理解其含义和行为。如果您想更精确地控制哪些错误被忽略,可能需要使用其他方法来进行检查和插入操作。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月7日
  • 已采纳回答 1月7日
  • 创建了问题 11月16日