我运行了一个脚本,每秒更新一次DB中的某些值。 在脚本开始时,我首先连接到DB:
conn = pymysql.connect(host= "server",
user="user",
passwd="pw",
db="db",
charset='utf8')
x = conn.cursor()
我打开连接打开脚本的运行时间(大约30分钟)
使用此代码,我每秒更新一次某些值:
query = "UPDATE missionFilesDelDro SET landLat = '%s', landLon='%s',landHea='%s' WHERE displayName='%s'" % (lat, lon, heading, mission)
x.execute(query)
conn.ping(True)
但是现在当我的Internet连接断开时,脚本也会崩溃,因为它无法更新变量。我的连接通常在一分钟内重新建立。 (该脚本在正在移动的车辆上运行。通过GSM调制解调器建立互联网连接)
在更新变量之前每次与服务器的连接重新打开是否更好,这样我才能看到连接是否已建立或是否有更好的方法?
答案 0 :(得分:1)
当连接断开时,我猜测脚本在x.execute(query)
行发生异常失败。
您可以捕获异常并重试打开连接。下面的'pseudo-python'演示了一般技术,但显然需要适应使用实际函数,方法和异常名称:
def open_connection(retries, delay):
for (x in range(0, retries)):
conn = pymysql.connection()
if (conn.isOpen()):
return conn
sleep(delay)
return None
conn = open_connection(30, 3)
x = conn.cursor()
while(conn is not None and more_data)
# read data here
query = ...
while(conn is not None): # Loop until data is definitely saved
try:
x.execute(query)
break # data saved, exit inner loop
except SomeException:
conn = open_connection(30,3)
x = conn.cursor()
一般的想法是,您需要循环并重试,直到数据被明确保存,或者直到您遇到不可恢复的错误。
嗯。如果您以恒定速率对数据进行采样或接收,但由于网络故障而只能不定期地发送数据,那么您就已经创建了一个典型的生产者 - 消费者问题。您需要一个线程来读取或接收数据,一个队列来保存任何积压,另一个线程来存储数据。有趣! ; - )
答案 1 :(得分:1)
您可以先ping通连接,而不是在查询之后,因为如果需要,应该重新连接。
设定:
conn = pymysql.connect(host= "server",
user="user",
passwd="pw",
db="db",
charset='utf8')
和每一秒:
query = "UPDATE missionFilesDelDro SET landLat = '%s', landLon='%s',landHea='%s' WHERE displayName='%s'" % (lat, lon, heading, mission)
conn.ping()
x = conn.cursor()
x.execute(query)
参考https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/connections.py#L872
在ping()之后但在execute()之前连接可能会丢失,然后会失败。对于处理您需要捕获错误,类似于
from time import sleep
MAX_ATTEMPTS = 10
# every second:
query = "UPDATE missionFilesDelDro SET landLat = '%s', landLon='%s',landHea='%s' WHERE displayName='%s'" % (lat, lon, heading, mission)
inserted = False
attempts = 0
while (not inserted) and attempts < MAX_ATTEMPTS:
attempts += 1
try:
conn.ping()
x = conn.cursor()
x.execute(query)
inserted = True
except StandardError: # it would be better to use the specific error, not StandardError
sleep(10) # however long is appropriate between tries
# you could also do a whole re-connection here if you wanted
if not inserted:
# do something
#raise RuntimeError("Couldn't insert the record after {} attempts.".format(MAX_ATTEMPTS))
pass