我有一本词典列表字典。为什么我选择这种奇怪的方法?这是网络抓取工作的一部分,其中我将大量网页的不同部分存储在不同的字典中。我有列名来跟踪数据。我没有订购dicts cos'我在Python 2.6.6上。
什么是更有效的方式来存储这些数据(字典到mysql)?每次我刮网站时,我都会创建一个临时表来存储数据以便进一步处理。我首先为id创建一个记录,然后更新该id的列。这样做有更快更有效的方法吗?谢谢!
的Python
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" ""
答案 0 :(得分:2)
简单地删除字典并插入它们:
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:任意数量的键值
答案 1 :(得分:0)
您可以做的一项改进是发布一个更新查询:
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中的所有值都具有相同的键,则可以遵循相同的逻辑在一个查询中发出所有插入。类似于"insert into deldictmysql (id, "+keys_part+") values "+(", ".join("(%s"+values_part+")" for i in range(len(mydict)))) % query_values
(请原谅我最后的)
系列:))并相应地构建query_values
。
另外,正如我注意到你从print语句中使用Python 2.7,我相信你最好使用iteritems
代替items
,它返回迭代器而不是列表,如果词典中有很多项目,这很方便。
所有这一切中最重要的是你没有对你的查询进行消毒,这很糟糕。这里的问题是你不能使用经典的c.execute(sql, params)
来绑定params,因为即使列名是动态的,这也不包括在内。因此,您必须手动清理这些内容,并且还必须 信任 密钥,因为您可能无法对其进行清理。
这将大致给你:
values.append(MySQLdb.escape_string(finalvalue))
附加值时。
请注意,这只是让您了解可以执行的操作,并且在许多情况下会失败。
希望它有所帮助。
答案 2 :(得分:0)
json
模块序列化为文本。