2011-10-20 25 views
8

couchdb.pyを使用してデータベースを作成および更新しようとしています。できれば連続モードで通知の変更を実装したいと思います。以下に掲載されたテストコードを実行すると、私は変更の仕組みがどのようにPython内で動作するのか分かりません。couchdb-python変更通知

class SomeDocument(Document): 

############################################################################# 

# def __init__ (self): 

    intField = IntegerField()#for now - this should to be an integer 
    textField = TextField() 

couch = couchdb.Server('http://127.0.0.1:5984') 
databasename = 'testnotifications' 

if databasename in couch: 
    print 'Deleting then creating database ' + databasename + ' from server' 
    del couch[databasename] 
    db = couch.create(databasename) 
else: 
    print 'Creating database ' + databasename + ' on server' 
    db = couch.create(databasename) 

for iii in range(5): 

    doc = SomeDocument(intField=iii,textField='somestring'+str(iii)) 
    doc.store(db) 
    print doc.id + '\t' + doc.rev 

something = db.changes(feed='continuous',since=4,heartbeat=1000) 

for iii in range(5,10): 

    doc = SomeDocument(intField=iii,textField='somestring'+str(iii)) 
    doc.store(db) 
    time.sleep(1) 
    print something 
    print db.changes(since=iii-1) 

db.changes(since=iii-1) 

は、関心のある情報を返しますが、私はシーケンスまたはリビジョン番号、または文書情報を抽出する方法を働いていない、そこから形式で:

一方
{u'last_seq': 6, u'results': [{u'changes': [{u'rev': u'1-9c1e4df5ceacada059512a8180ead70e'}], u'id': u'7d0cb1ccbfd9675b4b6c1076f40049a8', u'seq': 5}, {u'changes': [{u'rev': u'1-bbe2953a5ef9835a0f8d548fa4c33b42'}], u'id': u'7d0cb1ccbfd9675b4b6c1076f400560d', u'seq': 6}]} 

、私が使用することに本当に興味コード:

db.changes(feed='continuous',since=4,heartbeat=1000) 

CouchDBのguideが示唆するように、ジェネレータオブジェクトを返しますし、彼らが来るよう通知を提供するためには表示されません....

は、誰もが成功しCouchDBの-pythonでの変更を使用していますか?

+0

さらに、リモートサーバ(Cloudantなど)で使用すると、 'since' oparg ....という編集エラーが発生します。これは、クラウドがリビジョンを文字列ではなく整数として保存しないためです。 since引数をさらに混乱させます! – radpotato

答えて

7

私は長いポーリングを連続して使用するのではなく、それは私にとってはうまくいきます。ロングポーリングモードでは、少なくとも1回の変更が発生するまでブロックしてから、すべての変更をジェネレータオブジェクトに戻します(db.changes)。

ここに私が変更を処理するために使用するコードがあります。 settings.dbは私のCouchDBデータベースオブジェクトです。

since = 1 
while True: 
    changes = settings.db.changes(since=since) 
    since = changes["last_seq"] 
    for changeset in changes["results"]: 
     try: 
      doc = settings.db[changeset["id"]] 
     except couchdb.http.ResourceNotFound: 
      continue 
     else: 
      // process doc 

あなたはそれが我々が各反復でchangesを呼び出す無限ループだ見ることができるように。 changesの呼び出しは、最新の更新のシーケンス番号と変更されたオブジェクトの2つの要素を含む辞書を返します。次に、それぞれの結果をループして適切なオブジェクトをロードし、処理します。

連続供給の場合、while True:の代わりにfor changes in settings.db.changes(feed="continuous", since=since)を使用してください。

4

私はこれと同様の方法でメールスプーラを設定しました。 couchdb.Session()もロードする必要があります。スプーラ変更フィードへの未送信メールのみを受信するためのフィルタも使用します。

from couchdb import Server 

    s = Server('http://localhost:5984/') 
    db = s['testnotifications'] 
    # the since parameter defaults to 'last_seq' when using continuous feed 
    ch = db.changes(feed='continuous',heartbeat='1000',include_docs=True) 

    for line in ch: 
     doc = line['doc'] 
     // process doc here 
     doc['priority'] = 'high' 
     doc['recipient'] = 'Joe User' 
     # doc['state'] + 'sent' 
     db.save(doc) 

これは、あなたが合うようにデータを操作し、フィード、そして最終的にあなたの文書を更新し、変更から直接ドキュメントにアクセスできるようになります。実際の 'db.save(doc)'のtry/exceptブロックを使用して、保存する前にドキュメントを編集して再ロードしている間にドキュメントが更新されたときに捕捉できます。

関連する問題