简体   繁体   English

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

[英]error while saving a dictionary into mysql table from python code

I am trying to save a dict into mysql table, whose keys are columns and values are rows.我正在尝试将 dict 保存到 mysql 表中,其键是列,值是行。 This dict has keys which is a subset of all the columns of a table.这个字典有键,它是表中所有列的子集。 I am using below code in python我在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}
sql_insert_query = """ INSERT INTO Data {} VALUES {}""".format(tuple(sql_dict.keys()), tuple(sql_dict.values()))

I get an error when i run my code运行代码时出现错误

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'

I don't understand where am I going wrong.我不明白我哪里出错了。 Can someone help me with this ?有人可以帮我弄这个吗 ?

My table desc for reference我的表供参考

在此处输入图片说明

Use the following syntax to insert values into your database使用以下语法将值插入到数据库中

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))
cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

Else you are opening yourself to SQL injection attacks.否则,您将面临 SQL 注入攻击。 https://xkcd.com/327/ https://xkcd.com/327/

Another problem is the keys in your dictionary don't match the table columns in your screenshot.另一个问题是字典中的键与屏幕截图中的表列不匹配。 deviceID until rssi matches but CH_1_Leavinng_Chiller_Liq_Temp doesn't match. deviceID直到rssi匹配但CH_1_Leavinng_Chiller_Liq_Temp不匹配。 So the error likely comes from here.所以错误很可能来自这里。

edit :编辑
From your example this would be the SQL query:从您的示例中,这将是 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
)"

The datatype for counter and rssi is varchar . counterrssi的数据类型是varchar Here you are however providing a number, not string.但是,在这里您提供的是数字,而不是字符串。

You can't use tuple to format SQL strings as you are doing, for a couple of reasons:出于以下几个原因,您不能像现在一样使用tuple来格式化 SQL 字符串:

  • It doesn't work for table column names, because they should not be surrounded with single quotes.它不适用于表列名,因为它们不应该用单引号括起来。 Surround them with backticks instead, so your INSERT statement looks like用反引号包围它们,所以你的INSERT语句看起来像
    INSERT INTO Data (`deviceId`, `date`, `timestamp`, ...
  • If a string value contains a ' character, this will cause Python to output the string using double-quote rather than single-quote characters.如果字符串值包含'字符,这将导致 Python 使用双引号而不是单引号字符输出字符串。 Whether MySQL accepts double-quoted string literals or not I don't know, but other databases definitely don't.我不知道 MySQL 是否接受双引号字符串文字,但其他数据库肯定不接受。 There is also, as pointed out by @TinNguyen, the risk of SQL injection, so you should be using parameterised SQL for your string values.正如@TinNguyen 指出的那样,还有 SQL 注入的风险,因此您应该对字符串值使用参数化 SQL。

Instead, try something like the following:相反,请尝试以下操作:

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

Here, we build up the parts of the INSERT statement using the .join() method on strings: it looks a bit odd because it's a method on the joining string, ", " .在这里,我们使用字符串上的.join()方法构建INSERT语句的部分:它看起来有点奇怪,因为它是连接字符串", " Note that neither of column_names nor placeholders begin nor end with parentheses ( and ) so these must be added to the SQL string we call .format() on: I've replaced both occurrences of {} with ({}) .请注意, column_namesplaceholders都不是以括号( and )开头或结尾,因此必须将它们添加到我们调用.format()的 SQL 字符串中:我已将{}两次出现替换为({})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM