Python CouchDB无法保存从feedparser条目创建的dict? (没有属性'读')

时间:2011-03-31 20:04:05

标签: python couchdb feedparser

我有一个脚本,我想读取RSS提要中的条目,并将JSON格式的各个条目存储到CouchDB数据库中。

我的代码中有趣的部分看起来像这样:

Feed = namedtuple('Feed', ['name', 'url'])

couch = couchdb.Server(COUCH_HOST)
couch.resource.credentials = (COUCH_USER, COUCH_PASS)

db = couch['raw_entries']

for feed in map(Feed._make, csv.reader(open("feeds.csv", "rb"))):
    d = feedparser.parse(feed.url)
    for item in d.entries:
        db.save(item)

当我尝试运行该代码时,我从db.save(item)

收到以下错误
AttributeError: object has no attribute 'read'

好的,我接着做了一点调试......

for feed in map(Feed._make, csv.reader(open("feeds.csv", "rb"))):
    d = feedparser.parse(feed.url)
    for item in d.entries:
        print(type(item))

导致<class 'feedparser.FeedParserDict'> - 啊,所以feedparser正在使用自己的dict类型......好吧,如果我尝试将其明确地转换为dict怎么办?

for feed in map(Feed._make, csv.reader(open("feeds.csv", "rb"))):
    d = feedparser.parse(feed.url)
    for item in d.entries:
        db.save(dict(item))

Traceback (most recent call last):
  File "./feedchomper.py", line 32, in <module>
    db.save(dict(item))
  File "/home/dealpref/lib/python2.7/couchdb/client.py", line 407, in save
_, _, data = func(body=doc, **options)
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 399, in post_json
status, headers, data = self.post(*a, **k)
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 381, in post
**params)
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 419, in _request
credentials=self.credentials)
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 239, in request
    resp = _try_request_with_retries(iter(self.retry_delays))
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 196, in _try_request_with_retries
    return _try_request()
  File "/home/dealpref/lib/python2.7/couchdb/http.py", line 222, in _try_request
    chunk = body.read(CHUNK_SIZE)
AttributeError: 'dict' object has no attribute 'read'

W-什么?这没有意义,因为以下工作正常,类型仍然是dict

some_dict = dict({'foo': 'bar'})
print(type(some_dict))
db.save(some_dict)

我在这里缺少什么?

3 个答案:

答案 0 :(得分:4)

我找到了一种方法,通过将结构序列化为JSON,然后回到我传递给CouchDB的Python字典 - 然后将其重新序列化为JSON以保存(是的,奇怪且不利,但它有效吗?)

我必须为转储执行自定义序列化方法,因为repr的{​​{1}}不能是time_struct d。

来源:http://diveintopython3.org/serializing.html

代码:

eval

答案 1 :(得分:4)

在邮件列表上回答,但基本上这种情况发生了,因为feedbparser条目包含无法无损地序列化为JSON的数据,例如time.struct_time实例。不幸的是,couchdb-python继续假设它是一个文件,掩盖了实际的错误。

答案 2 :(得分:1)

也许 Python CouchDB中存在一个错误。你可以说它接受的东西不够自由。

但是,基本上,CouchDB存储JSON。您应该使用您所用语言的“JSON”。显然,Python意味着dict个对象。

在调用CouchDB之前,您可能会得到最好的解决方法,了解如何将所有类型转换为普通的Python dict。也许这不是最“正确”的解决方案,但我怀疑它是最快的。

我的Python生疏了。 dict(foo)是否有可能返回非字典?也许FeedParserDict子类dict然后在调用dict()时使用元编程返回自身?你能否确认type(dict(item))绝对是一个简单的Python词典?

Javascript领域的一个常见技巧是通过序列化程序(如JSON)进行往返。像pickle.loads(pickle.dumps(item))这样的东西。这几乎可以保证您拥有核心数据的简单副本。