1

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

3 回答 3

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:适用于任意数量和值的键

于 2012-06-26T22:00:22.290 回答
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 时,我相信您最好使用iteritemsinstead of items,它返回一个迭代器而不是一个列表,如果您的字典中有很多项目,这很方便。

在这一切中最重要的是你没有清理你的查询,这很糟糕。这里的问题是您不能使用经典的c.execute(sql, params), 来绑定参数,因为即使列名也是动态的,这没有涵盖。所以你必须手动清理这些,并且还要信任密钥,因为你可能无法清理这些。

这将大致为您提供:

values.append(MySQLdb.escape_string(finalvalue))

附加值时。

请注意,这只是让您了解可以做什么,并且在许多情况下会失败。

希望能帮助到你。

于 2012-06-26T22:04:23.167 回答
0
  1. 考虑使用 redis 之类的东西来存储这类数据。
  2. 您可以使用该json模块将其序列化为文本。
于 2012-06-26T22:25:53.577 回答