【问题标题】:Load table from Oracle to MYSQL using python使用python将表从Oracle加载到MYSQL
【发布时间】:2020-08-28 14:20:19
【问题描述】:

尝试使用以下代码将行从 Source(Oracle) 加载到 Target(MYSQL)

for row in source_cursor:
        target_cursor.execute("INSERT INTO JOB (SUBJECT_AREA,WORKFLOW_NAME,VERSION_NUMBER,SUBJECT_ID,WORKFLOW_ID,WORKFLOW_RUN_ID,WORKLET_RUN_ID,CHILD_RUN_ID,INSTANCE_ID,INSTANCE_NAME,TASK_ID,TASK_TYPE_NAME,TASK_TYPE,START_TIME,END_TIME,RUN_ERR_CODE,RUN_ERR_MSG,RUN_STATUS_CODE,TASK_NAME,TASK_VERSION_DECIMAL,SERVER_ID,SERVER_NAME)   VALUES(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22)",(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20],row[21]))

错误

 File "/usr/local/lib/python2.7/site-packages/MySQLdb/cursors.py", line 187, in execute
    query = query % tuple([db.literal(item) for item in args])
TypeError: not all arguments converted during string formatting

已编辑 更新代码_:-

SQL="SELECT SUBJECT_AREA, WORKFLOW_NAME, VERSION_NUMBER, SUBJECT_ID, WORKFLOW_ID, WORKFLOW_RUN_ID, WORKLET_RUN_ID, CHILD_RUN_ID, INSTANCE_ID, INSTANCE_NAME,TASK_ID, TASK_TYPE_NAME, TASK_TYPE, TO_CHAR(START_TIME, 'YYYY/MM/DD HH24:MI:SS'), TO_CHAR(END_TIME, 'YYYY/MM/DD HH24:MI:SS'), RUN_ERR_CODE, RUN_ERR_MSG, RUN_STATUS_CODE, TASK_NAME, TASK_VERSION_NUMBER, SERVER_ID, SERVER_NAME FROM JOB WHERE TRUNC(END_TIME) = TRUNC(SYSDATE) or END_TIME IS NULL"

source_cursor = connection.cursor()
source_query=source_cursor.execute(SQL)

target_cursor = myDB.cursor()
sql = """INSERT INTO JOB_target (SUBJECT_AREA, WORKFLOW_NAME, VERSION_NUMBER,SUBJECT_ID, WORKFLOW_ID, WORKFLOW_RUN_ID, WORKLET_RUN_ID,CHILD_RUN_ID, INSTANCE_ID, INSTANCE_NAME, TASK_ID, TASK_TYPE_NAME, TASK_TYPE, START_TIME, END_TIME, RUN_ERR_CODE,RUN_ERR_MSG, RUN_STATUS_CODE, TASK_NAME, TASK_VERSION_DECIMAL,SERVER_ID, SERVER_NAME)  VALUES({prms})""".format(prms=", ".join(['%s'] * 22))
target_cursor.executemany(sql, [row for row in source_cursor])
source_cursor.close()
target_cursor.close()
connection.close()

错误:

mysql_connection_v2.py:40: Warning: Data truncated for column 'START_TIME' at row 1
  target_cursor.executemany(sql, [row for row in source_cursor])
mysql_connection_v2.py:40: Warning: Data truncated for column 'START_TIME' at row 2
  target_cursor.executemany(sql, [row for row in source_cursor])
mysql_connection_v2.py:40: Warning: Data truncated for column 'START_TIME' at row 3
  target_cursor.executemany(sql, [row for row in source_cursor])
mysql_connection_v2.py:40: Warning: Data truncated for column 'START_TIME' at row 4

【问题讨论】:

  • 请显示source_cursor() 的定义。它在executefetchall 之后运行吗?
  • Parfait,我已编辑代码以提供更清晰的图片

标签: python mysql sql oracle mysql-python


【解决方案1】:

在 Python 中,尽管所有人都努力遵守 PEP 249,但没有两个 DB-API 完全相同,尤其是在参数实现方面。具体来说,虽然cxOracle 模块支持任意占位符,如编号序列:1:2:3 等,但模块MySQLdb 仅支持%s%(name)s 参数样式。

因此,相应地调整准备好的 SQL 语句。此外,考虑format 通过列表动态写入占位符 (["%s", "%s", %s", ...]) 以避免长时间未编号的写出和executemany 以避免循环。

sql = """INSERT INTO JOB (SUBJECT_AREA, WORKFLOW_NAME, VERSION_NUMBER, 
                          SUBJECT_ID, WORKFLOW_ID, WORKFLOW_RUN_ID, WORKLET_RUN_ID, 
                          CHILD_RUN_ID, INSTANCE_ID, INSTANCE_NAME, TASK_ID, 
                          TASK_TYPE_NAME, TASK_TYPE, START_TIME, END_TIME, RUN_ERR_CODE,
                          RUN_ERR_MSG, RUN_STATUS_CODE, TASK_NAME, TASK_VERSION_DECIMAL, 
                          SERVER_ID, SERVER_NAME)   
         VALUES({prms})
      """.format(prms=", ".join(['%s'] * 22))

target_curosr.excecutemany(sql, tuple(source_cursor))
connection.commit()

但是,如果您使用的是循环,只需传递行本身,而不是解包其中的每个元素或使用索引到需要的点:

for row in source_cursor:
     target_cursor.execute(sql, row)

for row in source_cursor:
     target_cursor.execute(sql, row[:21])

【讨论】:

  • 对此,我要补充一点,从 Oracle DB 获取数据时,请确保调整 Cursor.arraysize,因为您可能会获取多行。见Tuning Fetch Performance
  • 冻糕,我已经编辑了描述。我收到了错误警告。
  • 这不是错误,而是在 MySQL 中该列的数据被截断的警告。考虑修改START_TIME 上的Oracle 查询以与MySQL 对齐?也许您使用的是date 而不是datetime?另外,您是否看到 MySQL 中附加的数据?请务必commit 更改。此外,您也许可以只传递 tuple(source_cursor) 而不是列表推导。
  • 正确,MYSQL 中的数据类型不同。非常感谢,冻糕(完美):)
猜你喜欢
  • 2020-04-03
  • 2014-04-24
  • 2020-09-01
  • 2012-01-04
  • 1970-01-01
  • 2015-07-31
  • 1970-01-01
  • 2018-10-12
  • 2021-10-02
相关资源
最近更新 更多