从python代码将字典保存到mysql表时出错

从python代码将字典保存到mysql表时出错,python,mysql,Python,Mysql,我试图将dict保存到mysql表中,该表的键是列,值是行。此dict具有键,键是表中所有列的子集。我在python中使用以下代码 sql_dict = {'deviceID': 'fd00::212:4b00:1957:d1b1', 'date': '2020-02-22', 'timestamp': '18:39:29.620329', 'counter': 72, 'rssi': 59, 'CH_1_Leavinng_Chiller_Liq_Temp': 7.7, 'CH_1_Motor_

我试图将dict保存到mysql表中,该表的键是列,值是行。此dict具有键,键是表中所有列的子集。我在python中使用以下代码

sql_dict = {'deviceID': 'fd00::212:4b00:1957:d1b1', 'date': '2020-02-22', 'timestamp': '18:39:29.620329', 'counter': 72, 'rssi': 59, 'CH_1_Leavinng_Chiller_Liq_Temp': 7.7, 'CH_1_Motor_Current_limit_SP': 7.8, 'CH_1_Leaving_Condensor_liq_temp': 36.1, 'CH_1_Motor_Current_Percentage': 9.9, 'CH_1_Discharge_temp': 45.1, 'CH_1_Oil_Sump_temp': 45.6, 'CH_1_Remote_start_stop': 0.0, 'CH_1_Variable_speed_type': 0.0, 'Bypass line temp sensor ': -1274.8}
我运行代码时出错

Failed inserting record into python_users table 1064 (42000): 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 ''deviceID', 'date', 'timestamp', 'counter', 'rssi', 'CH_1_Leavinng_Chiller_Liq_T'
我不明白我错在哪里。有人能帮我吗

我的表格描述供参考


使用以下语法将值插入数据库

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))
否则,您将面临SQL注入攻击

另一个问题是字典中的键与屏幕截图中的表列不匹配<代码>设备ID直到<代码>rssi匹配,但<代码>冷却液冷却器温度不匹配。所以错误可能来自这里

编辑
根据您的示例,这将是SQL查询:

INSERT INTO Data (
  'deviceID', 'date', 'timestamp', 
  'counter', 'rssi', 'CH_1_Leavinng_Chiller_Liq_Temp', 
  'CH_1_Motor_Current_limit_SP', 'CH_1_Leaving_Condensor_liq_temp', 'CH_1_Motor_Current_Percentage', 
  'CH_1_Discharge_temp', 'CH_1_Oil_Sump_temp', 'CH_1_Remote_start_stop', 
  'CH_1_Variable_speed_type', 'Bypass line temp sensor '
) VALUES (
  'fd00::212:4b00:1957:d1b1', '2020-02-22', '18:39:29.620329', 
  72, 59, 7.7, 
  7.8, 36.1, 9.9, 
  45.1, 45.6, 0.0, 
  0.0, -1274.8
)"

counter
rssi
的数据类型是
varchar
。但是,这里您提供的是一个数字,而不是字符串。

您不能使用
tuple
格式化SQL字符串,原因如下:

  • 它不适用于表列名,因为它们不应该用单引号括起来。相反,用反勾号环绕它们,因此您的
    INSERT
    语句如下所示
插入数据(`deviceId`、`date`、`timestamp`、。。。
  • 如果字符串值包含
    字符,这将导致Python使用双引号而不是单引号字符输出字符串。我不知道MySQL是否接受双引号字符串文本,但其他数据库肯定不接受。正如@TinNguyen所指出的,还有SQL注入的风险,所以u应该对字符串值使用参数化SQL
相反,请尝试以下方法:

column_names = ", ".join("`{0}`".format(key) for key in sql_dict)
placeholders = ", ".join(["%s"] * len(sql_dict))
sql_insert_query = """ INSERT INTO Data ({}) VALUES ({})""".format(column_names, placeholders)
# execute the insert using cursor.execute(sql_insert_query, tuple(sql_dict.values()))

在这里,我们使用字符串上的
.join()
方法构建
INSERT
语句的各个部分:它看起来有点奇怪,因为它是连接字符串上的一个方法,
,“
”。请注意,
列名
占位符
都不是以括号开始或结束的
因此必须将它们添加到我们调用的SQL字符串
.format()
上:我已经用
({})替换了两个出现的
{}

打印出
SQL\u dict.keys()
元组(SQL\u dict.values())
。似乎是一个特殊字符导致了这种情况。出现问题的原因是varchar值周围缺少引号,因为生成的字符串类似于插入到数据中的
(abcd:casd,)
但是按照@Tin Nguyen的回答,我的sql dict不断变化,这就是我尝试这样做的原因,填充dict中的那些列,其余为空。我没有显示我表格的完整列。
Chu 1_Leaving_Cooller_Liq_Temp
也是一个列,我注意到了另一个问题。如果这不能解决问题,请在问题中包含
CREATE…
sql查询。您可以从中推断出有效的
INSERT…
sql查询。我不想硬编码。如何使用类似
sql\u INSERT\u query=“”INSERT-INTO-data-key\u-tuple-value\u-tuple”的内容
我的编辑是否解决了您的原始问题?您可以根据字典中的项目数量动态地将字符串
插入到数据(?,?)值(?,?)
中。在python控制台中运行此操作
“,”。join([“?”]*5)
5您可以根据字典项的数量设置变量。我还编辑了
插入到…
语法,因为我不知道您使用的是哪种语法。这取决于您的库。您必须尝试一下。
column_names = ", ".join("`{0}`".format(key) for key in sql_dict)
placeholders = ", ".join(["%s"] * len(sql_dict))
sql_insert_query = """ INSERT INTO Data ({}) VALUES ({})""".format(column_names, placeholders)
# execute the insert using cursor.execute(sql_insert_query, tuple(sql_dict.values()))