2016-08-06 11 views
0

私はpythonスクリプトをsqlite3の代わりにmysqlを使用するように変換しています。私はこの点を本当に困惑させたmysql構文エラーに多くの問題があります。私はデータベースに関する多くの経験がありません。それは短い時間の後、彼らはエラーをスローするラインが動作するようです。Pythonでmysqlをsqlite3に変換する

これは私に最初のエラーを与える行です。私は文法の権利を得ると、他のものもすべて変更できると思います。

 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(フォーマットと右のトラックに私を設定するための任意の助けをいただければ幸い1064エラーがスローされます一番下に「UPDATE文字列。実行上記のコードシリアル文字列がで来るときシリアル文字列中の「センサー」。カンマで区切られたセンサーの測定値が続いている。コードが挿入けど更新していないとき、[OK]を動作するようです。事前に

おかげでここ

がフルエラーコード

です
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") 
私はそれがステータス列であるとして、ステータスフィールドをrecogninzeていない何らかの理由で、次のコード

  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)) 

に到達するまで、私はこれが動作しているようだセットアップするには、以下のSQL UPDATE文を第三の例を使用している

その代わりにこのエラーをスローします。

(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」を使用しようとします状態"。

+0

問題のクエリと完全なエラーメッセージを投稿した方が理にかなっていますか? – e4c5

+0

update_sqlの前に "print"を置いて、出力するもの、動作するものと出力しないものを表示します。そしてyes @ e4c5は正しいです、エラーメッセージは役に立ちます – cox

+0

また、SQLAlchemy;のようないくつかのDBMS-agnosticフレームワークを次回使用するための良い教訓です! –

答えて

0

は構文的には、あなたのUPDATEのSQLステートメントは、等号とカンマのSET句と配置に従って正しいです。ほとんどの場合、21個の変数のうちの1つ以上が、MySQLが数字列に設定できない長さゼロの文字列('')を返しています。このようなゼロ長の文字列を条件付きでNoneに変換することを検討してください。これは、MySQLでNULLと解釈されます。一例として、以下

は条件付きような長さゼロの文字列のNoneを生成し、解決するv5

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

に空の値を示しています

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 

したがって、以下の調整を考慮して変数が初期化されるときの上部に:

​​

そして、NoneTypeオブジェクトが連結と暗黙的ではない文字列の明示的な変換を必要とするのでstr()の各変数を包みます。あるいは、

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)) 

、内のパラメータ化クエリとして更新を実行するPythonのNoneのすべてのインスタンスでNULLにMySQLの列を設定します以下の更新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() 
+0

上記の例は、私が正しく動作したくない1行で困惑しているsqlite3行の一部を変換することから始めるのに非常に役立ちました。元のメッセージを更新して、作業を拒否する行を表示してくれました。ありがとうございました。 – Renegade

+0

私は許しても、最初の問題を変更しているようで、別の質問をする必要があるかもしれません。この回答では、最初に失敗した更新クエリの問題は、21の変数の1つの空の値から派生しましたか? – Parfait

+0

あなたの編集に関しては、単に 'Status'値を一重引用符で囲みます。これは、文字列のように見えるので、単純に' 'Status''値をラップしてください:' 'UPDATE pH2 SET Low = {}、High = {}、Status = '{}' pH2Value_Low、pH2Value_High、pH2_Status) ' – Parfait

関連する問題