2011-10-20 14 views
8

Estoy tratando de usar couchdb.py para crear y actualizar bases de datos. Me gustaría implementar cambios de notificación, preferiblemente en modo continuo. Ejecutando el código de prueba publicado a continuación, no veo cómo funciona el esquema de cambios dentro de Python.notificaciones de cambio de 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) 

El valor

db.changes(since=iii-1) 

devuelve información que es de interés, pero en un formato en el que no he descubierto cómo extraer los números de secuencia o de revisión, o la información de 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}]} 

Mientras tanto, el código que estoy muy interesado en el uso:

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

Devuelve un objeto generador y no parece proporcionar notificaciones a medida que llegan, como el CouchDB guide sugiere ....

alguien ha utilizado los cambios en couchdb-pitón con éxito?

+0

Además de estos problemas, cuando se utiliza con un servidor remoto (por ejemplo, Cloudant) se producen errores para la edición 'desde' oparg ...., esto parece ser porque cloudant no almacena las revisiones como enteros, sino como cadenas, ¡lo cual hace que el argumento since sea aún más confuso! – radpotato

Respuesta

7

Utilizo largas encuestas en lugar de continuas, y eso funciona bien para mí. En el modo de sondeo largo db.changes bloques hasta que se haya producido al menos un cambio, y luego devuelve todos los cambios en un objeto del generador.

Aquí está el código que uso para manejar los cambios. settings.db es mi objeto de base de datos 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 

Como se puede ver que es un bucle infinito en el que llamamos changes en cada iteración. La llamada al changes devuelve un diccionario con dos elementos, el número de secuencia de la actualización más reciente y los objetos que se modificaron. Luego recorro cada resultado cargando el objeto apropiado y procesándolo.

Para una alimentación continua, en lugar de la línea while True: use for changes in settings.db.changes(feed="continuous", since=since).

4

Configuré un mailspooler usando algo similar a esto. También deberás cargar couchdb.Session() También uso un filtro para recibir solo correos no enviados al feed de cambios de la cola de impresión.

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) 

Esto le permitirá acceder a su documento directamente de los cambios alimentar, manipular los datos como mejor le parezca, y finalmente modificar sus documentos. Utilizo un bloque try/except en el 'db.save (doc)' real para poder ver cuándo se actualizó un documento mientras editaba y volver a cargar el documento antes de guardarlo.

Cuestiones relacionadas