Python将数据发送到MySQL DB

时间:2017-12-07 21:45:40

标签: python mysql

我运行了一个脚本,每秒更新一次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调制解调器建立互联网连接)

在更新变量之前每次与服务器的连接重新打开是否更好,这样我才能看到连接是否已建立或是否有更好的方法?

2 个答案:

答案 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