如何保持连续写入 Oracle table 即使 table 不可访问?

How to keep continuously write to Oracle table even if table is not accessible?

我正在尝试将多条记录连续插入到一个 Oracle table 中。为此,我在下面编写了 python 脚本。

import cx_Oracle
import config

connection = None
try:
    # Make a connection
    connection = cx_Oracle.connect(
        config.username,
        config.password,
        config.dsn,
        encoding=config.encoding)

    # show the version of the Oracle Database
    print(connection.version)

    # Insert 20000 records
    for i in range(1, 20001):
        cursor = connection.cursor()
        sql = "INSERT into SCHEMA.ABC (EVENT_ID, EVENT_TIME) VALUES( "+ str(i)+" , CURRENT_TIMESTAMP)"
        cursor.execute(sql)
        connection.commit()
except cx_Oracle.Error as error:
    print(error)
finally:
    if connection:
        connection.close()
    

因此,在插入期间,当我更改 table 名称时,它只是创建一个异常并从脚本中出来(因为 table 不可用且无法写入)。我想要的是,即使当我进行重命名并且 table 不可用时,脚本也需要不断尝试插入。有什么办法可以做到这一点吗?

这是 Ptit Xav 所谈论内容的示例。我添加了一些代码以在达到最大重试次数后退出,因为这通常是可取的。

# Insert 20000 records
for i in range(1, 20001):
    retry_count = 0
    data_inserted = False
    while not data_inserted:
        try:
            cursor = connection.cursor()
            sql = "INSERT into SCHEMA.ABC (EVENT_ID, EVENT_TIME) VALUES( "+ str(i)+" , CURRENT_TIMESTAMP)"
            cursor.execute(sql)
            connection.commit()
            data_inserted = True
        except cx_Oracle.Error as error:
            print(error)
            time.sleep(5) # wait for 5 seconds between retries
            retry_count += 1
            if retry_count > 100:
               print(f"Retry count exceeded on record {i}, quitting")
               break
    else:
        # continue to next record if the data was inserted
        continue
    # retry count was exceeded; break the for loop.
    break

有关 while... else 逻辑的更多说明,请参见 this answer

您可能希望将插入逻辑封装在一个 函数 中,以捕获可能的异常并执行重试

def safe_insert(con, i):
    """
    insert a row with retry after exception
    """
    retry_cnt = 0
    sql_text = "insert into ABC(EVENT_ID, EVENT_TIME) VALUES(:EVENT_ID,CURRENT_TIMESTAMP) "
    while True:
        try:
            with con.cursor() as cur:
                cur.execute(sql_text, [i])
                con.commit()
                return
        except cx_Oracle.Error as error:
            print(f'error on inserting row {i}')
            print(error)
            time.sleep(1)
            retry_cnt += 1
            if (retry_cnt > 10):
                raise error

与@kfinity 的回答类似,我还添加了一个重试限制 - 如果超出此限制,函数将引发异常。

另请注意,该函数在 INSERT 语句中使用 绑定变量 ,这优于 的串联在声明中。

用法就这么简单

for i in range(1, 20001): 
    safe_insert(con, i)