如何通过python将python字典存储到mysql DB中

时间:2013-10-31 09:48:43

标签: python mysql dictionary

我试图通过将字典转换为字符串然后尝试插入来将以下字典存储到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行“)

有任何建议或帮助吗?

5 个答案:

答案 0 :(得分:13)

首先,不要构造那样的原始SQL查询。永远不能。这是参数化查询的用途。你要求SQL injection攻击。

如果要存储任意数据(例如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()

答案 1 :(得分:1)

试试这个:

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

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

dbtable更改为您需要的值。

答案 2 :(得分: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 )   

答案 3 :(得分: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(变量),则需要将占位符{}括在引号中。

答案 4 :(得分: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)