Python CouchDB不能保存从feedparser条目创建的dict?(没有属性'read')

2024-10-03 21:33:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个脚本,我想读取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)中得到以下错误:

^{pr2}$

好的,所以我做了一些调试。。。在

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'>--ahh,所以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'

什么?这是没有道理的,因为下面的方法很好,而且类型仍然是dict

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

我错过了什么?在


Tags: csvinpyhomefordbsavelib
3条回答

我找到了一种方法,将该结构序列化为JSON,然后返回到我传递给CouchDB的Python dict,然后CouchDB会将其重新序列化回JSON以保存(是的,很奇怪,不好用,但它可以工作吗?)在

我必须为转储执行自定义序列化程序方法,因为time_structrepr不能是{}'d

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

代码:

#!/usr/bin/env python2.7

from collections import namedtuple
import csv
import json
import time

import feedparser
import couchdb

def to_json(python_object):
    if isinstance(python_object, time.struct_time):
        return {'__class__': 'time.asctime',
                '__value__': time.asctime(python_object)}

    raise TypeError(repr(python_object) + ' is not JSON serializable')

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

COUCH_HOST = 'http://mycouch.com'
COUCH_USER = 'user'
COUCH_PASS = 'pass'

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:
        j = json.dumps(item, default=to_json)
        db.save(json.loads(j))

在邮件列表中回答,但这基本上是因为feedbparser条目包含无法无损序列化为JSON的数据。时间结构时间实例。不幸的是,couchdb python接着假设它是一个文件,掩盖了实际的错误。在

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

但是,基本上,CouchDB存储JSON。您应该使用您的语言中的任何“JSON”。显然,对于Python,这意味着dict对象。在

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

我的Python生锈了。dict(foo)是否可能返回非dict?可能是FeedParserDict子类dict,然后在调用dict()时使用元编程返回自身?你能确认type(dict(item))绝对是一个纯Python dict吗?在

Javascript领域的一个常见技巧是通过JSON之类的序列化程序进行往返。像pickle.loads(pickle.dumps(item))。这基本上保证了核心数据的纯拷贝。在

相关问题 更多 >