2011-10-20 3 views
8

Sto cercando di utilizzare couchdb.py per creare e aggiornare i database. Mi piacerebbe implementare le modifiche alle notifiche, preferibilmente in modalità continua. Eseguendo il codice di test pubblicato di seguito, non vedo come lo schema delle modifiche funzioni all'interno di python.notifiche cambio 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) 

Il valore

db.changes(since=iii-1) 

restituisce le informazioni che è di interesse, ma in un formato da cui non ho trovato il modo di estrarre i numeri di sequenza o di revisione, o le informazioni del documento:

{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}]} 

nel frattempo, il codice sono molto interessato ad utilizzare:

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

Restituisce un oggetto generatore e non sembra fornire le notifiche così come arrivano, come CouchDB guide suggerisce ....

Qualcuno ha usato variazioni di CouchDB-pitone con successo?

+0

Oltre a questi problemi, quando si utilizza un server remoto (ad es. Cloudant) vengono lanciati errori per il comando "since" oparg .... edit - questo sembra essere dovuto al fatto che cloudant non memorizza le revisioni come numeri interi, piuttosto come stringhe, il che rende l'argomento since ancora più confuso! – radpotato

risposta

7

Io uso il polling lungo anziché continuo, e per me va bene. In modalità polling lungo db.changes blocchi fino a quando non è avvenuta almeno una modifica e quindi restituisce tutte le modifiche in un oggetto generatore.

Ecco il codice che uso per gestire le modifiche. settings.db è il mio oggetto CouchDB Database.

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 

Come si può vedere si tratta di un ciclo infinito in cui noi chiamiamo changes ad ogni iterazione. La chiamata a changes restituisce un dizionario con due elementi, il numero di sequenza dell'aggiornamento più recente e gli oggetti che sono stati modificati. Quindi eseguo il ciclo di ogni risultato caricando l'oggetto appropriato e elaborandolo.

Per un'alimentazione continua, invece della riga utilizzare for changes in settings.db.changes(feed="continuous", since=since).

4

Ho impostato un mailspooler usando qualcosa di simile a questo. Dovrai anche caricare couchdb.Session() Uso anche un filtro per ricevere solo e-mail non inviate allo spooler cambia il feed.

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) 

Questo vi permetterà di accedere tuo documento direttamente dalle modifiche da mangiare, manipolare i dati, come si vede in forma, e, infine, aggiornarvi documento. Io uso un try/except block sull'effettivo 'db.save (doc)' in modo da poter rilevare quando un documento è stato aggiornato mentre stavo modificando e ricaricare il documento prima di salvare.