如何以Pythonic方式在MySQL中存储Python词典列表?

时间:2012-06-26 21:13:32

标签: mysql database dictionary python

我有一本词典列表字典。为什么我选择这种奇怪的方法?这是网络抓取工作的一部分,其中我将大量网页的不同部分存储在不同的字典中。我有列名来跟踪数据。我没有订购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"  ""

3 个答案:

答案 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)

  1. 考虑使用像redis这样的东西存储这类数据。
  2. 您可以使用json模块序列化为文本。