14

我试图通过将字典转换为字符串然后尝试插入来将以下字典存储到 mysql DB 中,但我收到以下错误。如何解决这个问题,或者有没有其他方法可以将字典存储到 mysql DB 中?

dic = {'office': {'component_office': ['Word2010SP0', 'PowerPoint2010SP0']}}
d = str(dic)

# Sql query
sql = "INSERT INTO ep_soft(ip_address, soft_data) VALUES ('%s', '%s')" % ("192.xxx.xx.xx", d )

soft_data is a VARCHAR(500)

错误:执行异常(1064,“您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以在 'office' 附近使用正确的语法:{'component_office': ['Word2010SP0', 'PowerPoint2010SP0 '在第 1 行")

请问有什么建议或帮助吗?

4

5 回答 5

28

首先,永远不要构建这样的原始 SQL 查询。永远不能。这就是参数化查询的用途。您要求进行SQL 注入攻击。

如果要存储任意数据,例如 Python 字典,则应序列化该数据。JSON将是格式的不错选择。

总体而言,您的代码应如下所示:

import MySQLdb
import json

db = MySQLdb.connect(...)    
cursor = db.cursor() 

dic = {'office': {'component_office': ['Word2010SP0', 'PowerPoint2010SP0']}}
sql = "INSERT INTO ep_soft(ip_address, soft_data) VALUES (%s, %s)"

cursor.execute(sql, ("192.xxx.xx.xx", json.dumps(dic)))
cursor.commit()
于 2013-10-31T11:50:49.093 回答
1

更改您的代码如下:

dic = {'office': {'component_office': ['Word2010SP0', 'PowerPoint2010SP0']}}
d = str(dic)

# Sql query
sql = """INSERT INTO ep_soft(ip_address, soft_data) VALUES (%r, %r)""" % ("192.xxx.xx.xx", d )   
于 2013-10-31T10:44:02.857 回答
0

试试这个:

dic = { 'office': {'component_office': ['Word2010SP0', 'PowerPoint2010SP0'] } }

"INSERT INTO `db`.`table`(`ip_address`, `soft_data`) VALUES (`{}`, `{}`)".format("192.xxx.xx.xx", str(dic))

更改dbtable您需要的值。

于 2013-10-31T09:53:42.330 回答
0

清理输入是一个好主意,当需要在查询中多次使用相同的变量时,'.format' 很有用。(这个例子不是你要的)

dic = {'office': {'component_office': ['Word2010SP0', 'PowerPoint2010SP0']}}
ip = '192.xxx.xx.xx'
with conn.cursor() as cur:
  cur.execute("INSERT INTO `ep_soft`(`ip_address`, `soft_data`) VALUES ({0}, '{1}')".format(cur.escape(ip),json.dumps(event)))
  conn.commit()

如果不使用 cur.escape(variable),则需要将占位符 {} 括在引号中。

于 2018-10-12T16:45:17.077 回答
0

这个答案有一些关于连接对象的伪代码,mysql 的风格是 memsql,但除此之外它应该很容易理解。

import json
#... do something
a_big_dict = getAHugeDict()  #build a huge python dict
conn = getMeAConnection(...)
serialized_dict = json.dumps(a_big_dict) #serialize dict to string
#Something like this to hold the serialization...
qry_create = """
CREATE TABLE TABLE_OF_BIG_DICTS (
ROWID BIGINT NOT NULL AUTO_INCREMENT,
SERIALIZED_DICT BLOB NOT NULL,
UPLOAD_DT TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
KEY (`ROWID`) USING CLUSTERED COLUMNSTORE
);
"""
conn.execute(qry_create)
#Something like this to hold em'
qry_insert = """
INSERT INTO TABLE_OF_BIG_DICTS (SERIALIZED_DICT)
SELECT '{SERIALIZED_DICT}' as SERIALIZED_DICT;
"""
#Send it to db
conn.execute(qry_insert.format(SERIALIZED_DICT=serialized_dict))
#grab the latest
qry_read = """
SELECT a.SERIALIZED_DICT
from TABLE_OF_BIG_DICTS a
JOIN 
(
    SELECT MAX(UPLOAD_DT) AS MAX_UPLOAD_DT
    FROM TABLE_OF_BIG_DICTS
)                           b
ON  a.UPLOAD_DT = b.MAX_UPLOAD_DT
LIMIT 1
"""

#something like this to read the latest dict...
df_dict = conn.sql_to_dataframe(qry_read)
dict_str = df_dict.iloc[df_dict.index.min()][0]

#dicts never die they just get rebuilt
dict_better = json.loads(dict_str)
于 2020-03-25T16:02:21.830 回答