在python下将sqlite3转换为mysql

时间:2016-08-06 14:39:44

标签: python mysql sqlite

我正在将python脚本转换为使用mysql而不是sqlite3,而且我遇到了很多mysql语法错误的问题,这些错误实际上让我难以理解。我对数据库没有多少经验。似乎这些线条会在短时间内发挥作用,然后就会出错。

这是给我第一个错误的行。我想一旦我的语法正确,我也可以改变所有其他语法。

        elif 'Sensors' in line:
        Sensors,pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,TankTotal,Tank1,Tank2,Tank3,Tank4,WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4=line.split(",")
        Sensors = Sensors.replace("Read fail", "")
        WaterTempP4 = WaterTempP4.rstrip()
        elapsedTime = now-startTime
        elapsedSeconds = (elapsedTime.microseconds+(elapsedTime.days*24*3600+elapsedTime.seconds)*10**6)/10**6
        print("\033[10;0H\r")
        print("\033[10;0H(" + now.strftime("%Y/%m/%d %H:%M:%S") + ") Sensors: %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s"%(pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,TankTotal,Tank1,Tank2,Tank3,Tank4,WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4))
        now = datetime.now()
        delta = float(now.strftime('%s')) - float(LastDataPoint_Time.strftime('%s'))
        if (delta < 0):
            TimeString = LastDataPoint_Time.strftime("%Y-%m-%d %H:%M:%S")
            update_sql("DELETE FROM Sensors_Log WHERE Time='" + TimeString + "'")
            LastDataPoint_Time = datetime.now()
            addMessageLog("Negative Delta - Deleting Last Record (Wrong Time?)")
            printMessageLog()
        if (delta >= TakeDataPoint_Every) or (Datapoint_count == 0 and first_timesync == True):
            addMessageLog("Added a data point to the sensor values log.")
            printMessageLog()
            update_sql("INSERT INTO Sensors_Log (Time,pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,TankTotal,Tank1,Tank2,Tank3,Tank4,WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4) VALUES ('" + now.strftime("%Y-%m-%d %H:%M:%S") + "'," + pH1 + "," + pH2+ "," + Temp + "," + RH + "," + TDS1 + "," + TDS2 + "," + CO2 + "," + Light  + "," + Water + "," + MagX + "," + MagY + "," + MagZ + "," + TankTotal + "," + Tank1 + "," + Tank2 + "," + Tank3 + "," + Tank4 + "," + WaterTempP1 + "," + WaterTempP2 + "," + WaterTempP3 + "," + WaterTempP4 + ")")
            LastDataPoint_Time = datetime.now()
            timesync = 0 #do a timesync
            Datapoint_count = Datapoint_count + 1
        #SENSOR VALUES
        update_sql("UPDATE `Sensors` SET pH1 = " + pH1 + ", pH2 = " + pH2 + ", Temp = " + Temp + ", RH = " + RH + ", TDS1 = " + TDS1 + ", TDS2 = " + TDS2 + ", CO2 = " + CO2 + ", Light = " + Light + ", Water = " + Water + ", MagX = " + MagX + ", MagY = " + MagY + ", MagZ = " + MagZ + ", TankTotal = " + TankTotal + ", Tank1 = " + Tank1 + ", Tank2 = " + Tank2 + ", Tank3 = " + Tank3 + ", Tank4 = " + Tank4 + ", WaterTempP1 = " + WaterTempP1 + ", WaterTempP2 = " + WaterTempP2 + ", WaterTempP3 = " + WaterTempP3 + ", WaterTempP4 = " + WaterTempP4 + "")

        db.commit()

它的update_sql(“底部的UPDATE字符串会引发1064错误,任何帮助我将这个格式设置在正确的轨道上都会非常感激。上面的代码在串行字符串带有'传感器'时运行串口字符串。接下来是用逗号分隔的传感器读数。代码似乎在插入时工作正常,但没有更新。

提前致谢

这是完整的错误代码

Traceback (most recent call last):
  File "yieldbuddy.py", line 1211, in <module>
    serialerr=checkSerial()
  File "yieldbuddy.py", line 481, in checkSerial
    update_sql("UPDATE `Sensors` SET pH1 = " + pH1 + ", pH2 = " + pH2 + ", Temp = " + Temp + ", RH = " + RH + ", TDS1 = " + TDS1 + ", TDS2 = " + TDS2 + ", CO2 = " + CO2 + ", Light = " + Light + ", Water = " + Water + ", MagX = " + MagX + ", MagY = " + MagY + ", MagZ = " + MagZ + ", TankTotal = " + TankTotal + ", Tank1 = " + Tank1 + ", Tank2 = " + Tank2 + ", Tank3 = " + Tank3 + ", Tank4 = " + Tank4 + ", WaterTempP1 = " + WaterTempP1 + ", WaterTempP2 = " + WaterTempP2 + ", WaterTempP3 = " + WaterTempP3 + ", WaterTempP4 = " + WaterTempP4 + "")
  File "yieldbuddy.py", line 33, in update_sql
    cursor.execute(query)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1")

我一直在使用下面的第3个示例来设置sql update语句,这似乎正常工作,直到我达到以下代码

            elif 'SetPoint_pH2' in line:
            if oldSetPoint_pH2 != line:
                oldSetPoint_pH2 = line
                #print("%s"%(line))  For Debugging
                SetPoint_pH2,pH2Value_Low,pH2Value_High,pH2_Status=line.split(",")
                SetPoint_pH2 = SetPoint_pH2.replace("Read fail", "")
                pH2_Status = pH2_Status.rstrip()
                print("\033[16;0H                                                                                                                       ")
                print("\033[16;0H(" + now.strftime("%Y/%m/%d %H:%M:%S") + ") SetPoint_pH2: %s,%s,%s"%(pH2Value_Low,pH2Value_High,pH2_Status))
                #SetPoint_pH
#               update_sql("UPDATE `pH2` SET Low='" + pH2Value_Low + "',High='" + pH2Value_High + "',Status='" + pH2_Status + "'")
                update_sql("UPDATE `pH2` SET Low = {}, High = {}, Status = {}".format(pH2Value_Low,pH2Value_High,pH2_Status))

由于某种原因,它不会将状态字段识别为数据库中的状态列,而是抛出此错误。

(2016/08/07 12:10:42) SetPoint_pH2: -1.00,6.20,OK
Traceback (most recent call last):
  File "yieldbuddy.py", line 1310, in <module>
    serialerr=checkSerial()
  File "yieldbuddy.py", line 607, in checkSerial
    update_sql("UPDATE `pH2` SET Low = {}, High = {}, Status = {}".format(pH2Value_Low,pH2Value_High,pH2_Status))
  File "yieldbuddy.py", line 33, in update_sql
    cursor.execute(query)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 'OK' in 'field list'")

我似乎无法看到这一行与我已经完成的其他行之间的区别,它试图使用“ok”列,这实际上是我想要放入实际列“Status”的值。 / p>

1 个答案:

答案 0 :(得分:0)

从语法上讲,根据SET子句以及等号和逗号的放置,您的UPDATE SQL语句是正确的。最有可能的是,您的21个变量中的一个或多个返回一个零长度字符串(''),MySQL无法将其设置为数字列。考虑将这些零长度字符串有条件地转换为None,在MySQL中转换为NULL

例如,下面显示了v5

的空值
line = "this,is,a,test,"
v1, v2, v3, v4, v5 = line.split(",")
print(v5=='')
# TRUE

要解决此问题,请为此类零长度字符串有条件地生成None

v1, v2, v3, v4, v5 = [None if i == '' else i for i in [v1, v2, v3, v4, v5]]
print(v5==None)    # ALTERNATIVELY: print(v5 is None)
# TRUE

因此,在初始化变量时,请考虑顶部的以下调整:

...
Sensors,pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,TankTotal,\
Tank1,Tank2,Tank3,Tank4,WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4 = line.split(",")

Sensors,pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,TankTotal,\
Tank1,Tank2,Tank3,Tank4,WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4 = \
   [None if i == '' else i for i in [Sensors,pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,\
                                     MagX,MagY,MagZ,TankTotal,Tank1,Tank2,Tank3,Tank4,\
                                     WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4]]

然后,将每个变量包装在str()中,因为NoneType对象需要显式转换字符串而不是隐式连接。下面的更新会在Python NULL的每个实例中将MySQL列设置为None

update_sql("UPDATE `Sensors` SET pH1 = " + str(pH1) + ", " + \
            "pH2 = " + str(pH2) + ", Temp = " + str(Temp) + ", RH = " + str(RH) + ", " + \
            "TDS1 = " + str(TDS1) + ", TDS2 = " + str(TDS2) + ", CO2 = " + str(CO2) + ", " + \
            "Light = " + str(Light) + ", Water = " + str(Water) + ", MagX = " + str(MagX) + ", " + \
            "MagY = " + str(MagY) + ", MagZ = " + str(MagZ) + ", TankTotal = " + str(TankTotal) + ", " + \
            "Tank1 = " + str(Tank1) + ", Tank2 = " + str(Tank2) + ", Tank3 = " + str(Tank3) + ", " + \
            "Tank4 = " + str(Tank4) + ", WaterTempP1 = " + str(WaterTempP1) + ", " + \
            "WaterTempP2 = " + str(WaterTempP2) + ", WaterTempP3 = " + str(WaterTempP3) + ", " + \
            "WaterTempP4 = " + str(WaterTempP4) + "")

或者,考虑字符串格式也适用None

update_sql("UPDATE `Sensors` SET pH1 = {}, \
            pH2 = {}, Temp = {}, RH = {}, \
            TDS1 = {}, TDS2 = {}, CO2 = {},  \
            Light = {}, Water = {}, MagX = {},  \
            MagY = {}, MagZ = {}, TankTotal = {},  \
            Tank1 = {}, Tank2 = {}, Tank3 = {}, \
            Tank4 = {}, WaterTempP1 = {}, \
            WaterTempP2 = {}, WaterTempP3 = {}, \
            WaterTempP4 = {} ".format(pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,\
                                      MagX,MagY,MagZ,TankTotal,Tank1,Tank2,Tank3,Tank4,\
                                      WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4))

更好的是,在cursor.execute()方法中将更新作为参数化查询运行,如果源数据来自外部源以避免sql注入,则执行此操作:

cur.execute("UPDATE `Sensors` SET pH1 = %s, \
             pH2 = %s, Temp = %s, RH = %s, \
             TDS1 = %s, TDS2 = %s, CO2 = %s, \
             Light = %s, Water = %s, MagX = %s, \
             MagY = %s, MagZ = %s, TankTotal = %s, \
             Tank1 = %s, Tank2 = %s, Tank3 = %s,  \
             Tank4 = %s, WaterTempP1 = %s, \
             WaterTempP2 = %s, WaterTempP3 = %s, \
             WaterTempP4 = %s ", \
             (pH1,pH2,Temp,RH,TDS1,TDS2,CO2,Light,Water,MagX,MagY,MagZ,\
              TankTotal,Tank1,Tank2,Tank3,Tank4,\
              WaterTempP1,WaterTempP2,WaterTempP3,WaterTempP4)
db.commit()