我正在将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>
答案 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()