如何保持连续写入 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)
我正在尝试将多条记录连续插入到一个 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)