如何以Python的方式在MySQL中存储Python字典列表?
我有一本字典,里面有一大堆字典。我为什么选择这种奇怪的方法?这是我在不同的字典中存储大量网页的不同部分的网络抓取工作的一部分。我有列名来跟踪数据。我没有命令dicts,因为我使用的是Python 2.6.6 存储这些数据(从字典到mysql)的更有效的方法是什么?每次我浏览网站时,我都会创建一个临时表来存储数据,以便进一步处理。我首先为id创建一个记录,然后更新该id的列。有没有更快更有效的方法?谢谢大家! Python如何以Python的方式在MySQL中存储Python字典列表?,mysql,database,dictionary,python,Mysql,Database,Dictionary,Python,我有一本字典,里面有一大堆字典。我为什么选择这种奇怪的方法?这是我在不同的字典中存储大量网页的不同部分的网络抓取工作的一部分。我有列名来跟踪数据。我没有命令dicts,因为我使用的是Python 2.6.6 存储这些数据(从字典到mysql)的更有效的方法是什么?每次我浏览网站时,我都会创建一个临时表来存储数据,以便进一步处理。我首先为id创建一个记录,然后更新该id的列。有没有更快更有效的方法?谢谢大家! Python import MySQLdb db=MySQLdb.connect(db
import MySQLdb
db=MySQLdb.connect(db="mydb")
c=db.cursor()
mydict = {'1': [{'First': 'John', 'Last': 'Doe'}, {'Company': 'Trulia Inc.', 'Title': 'CEO', 'YearsattheCompany': 4}, {'Cell': '216-453-4322', 'Home': None}]}
for key, value in mydict.items():
id = key
c.execute("insert into deldictmysql (id) values (%s)" % id)
for eachdict in value:
print eachdict
for finalkey, finalvalue in eachdict.items():
print finalkey, finalvalue
if finalvalue:
query = "update deldictmysql set %s = '%s'"
c.execute(query % (finalkey, finalvalue))
c.close()
MySQL
create table deldictmysql (id integer, first varchar(40), last varchar(40), company varchar(200), title varchar(200), yearsatthecompany integer, cell varchar(20), home varchar(20));
输出
select * from deldictmysql;
"id" "first" "last" "company" "title" "yearsatthecompany" "cell" "home"
"1" "John" "Doe" "Trulia Inc." "CEO" "4" "216-453-4322" ""
只需将字典展平并插入即可:
def encoding(val):
if isinstance(val, unicode):
return val.encode('utf-8')
else:
return str(val)
for id, val in mydict.items():
data = dict(reduce(lambda x, y: x+y, [v.items() for v in val]) + [('id', id)])
sorted_keys = sorted(map(str, data.keys()))
sorted_vals = map(encoding, [v[k] for k in sorted_keys]) # sorted by keys
format = ', '.join(["'%s'"] * len(sorted_vals))
c.execute("insert into deldictmysql
(%s) values (%s)" % (', '.join(sorted_keys), format), sorted_vals)
UPD:对于任意数量和值的键您可以做的一个改进是发出一个更新查询:
for key, value in mydict.iteritems():
id = key
c.execute("insert into deldictmysql (id) values (%s)" % id)
for eachdict in value:
print eachdict
items = [item for item in eachdict.iteritems() if item[1]]
query_values = tuple(itertools.chain(*items))
query = "update deldictmysql set "+", ".join("%s = '%s'" for i in items)
c.execute(query % query_values)
甚至更好的是,只需一次插入查询:
for key, value in mydict.iteritems():
id = key
keys = []
values = []
for eachdict in value:
print eachdict
for finalkey, finalvalue in eachdict.iteritems():
if not finalvalue: continue
keys.append(finalkey)
values.append(finalvalue)
keys_part = ", ".join("%s" for k in keys)
values_part = ", ".join("'%s'" for v in values)
query_values = keys+[id]+values
c.execute("insert into deldictmysql (id, "+keys_part+") values (%s"+values_part+")" % query_values)
如果可以保证dict中的所有值都具有相同的键,那么可以按照相同的逻辑在一个查询中发出所有插入。类似于“插入deldictmysql(id,“+keys\u part+”)。值“+(”,“。连接((%s“+values\u part+”)范围内的i(len(mydict)))%query\u值
(请原谅后面的系列)
)并相应地构造query\u值
另外,正如我从print语句中注意到您正在使用Python2.7一样,我认为最好使用iterms
而不是items
,后者返回一个迭代器而不是列表,如果字典中有很多项,这会很方便
最重要的是你没有清理你的查询,这很糟糕。这里的问题是,您不能使用经典的c.execute(sql,params)
来绑定params,因为即使列名也是动态的,这并不包括在内。因此,您必须手动清理这些密钥,还必须信任密钥,因为您可能无法清理这些密钥
这将为您大致提供以下信息:
values.append(MySQLdb.escape_string(finalvalue))
在附加值时
请注意,这只是让您了解可以做什么,并且在许多情况下会失败
希望能有帮助
json
模块将其序列化为文本这假设dict将始终具有相同的键。而且dict的键有第一个大写字母(但这只是一个细节)。@jadkik94更新。适用于任何键(MySQL保留字除外)。这种方法甚至更好:MySQLdb lib.data=dict(reduce(lambda x,y:x+y,[v.items()代表val中的v]+[('id',id)])将转义并将None映射到NULL。TypeError:只能将list(而不是“tuple”)连接到list。这是错误的。谢谢你!它抱怨“UnicodeEncodeError:'ascii'编解码器无法对字符进行编码”@::convertsorted_vals=[str(v[k]),表示排序_键中的k。如何优雅地处理它,试着抓住唯一的出路?@ThinkCode如果使用“忽略”,您的程序不会保存®字符或任何其他非ascii字符(例如,任何外语的文本)。要保存所有这些字符,请尝试使用更新的代码。您只需添加“encoding”函数,并将行替换为排序的(排序的)vals:sorted(排序的)vals=map(编码,[v[k]表示排序的)#按键排序的数据总是希望排序的!)但我同意NoSQL。