2012-05-22 14 views
6

Soy muy nuevo en el sofá, pero estoy tratando de usarlo en un nuevo proyecto de Python, y me gustaría usar Python para escribir los documentos de diseño (vistas) también. Ya configuré Couch para usar el servidor de vistas en sofá, y puedo confirmar que esto funciona ingresando algunas funciones simples de mapa/reducción en Futon.Método recomendado para cargar documentos de diseño CouchDB en Python?

¿Hay alguna recomendación oficial sobre cómo cargar/sincronizar documentos de diseño cuando se utiliza el módulo couchdb de Python?

Entiendo que puedo publicar documentos de diseño para "instalarlos" en Couch, pero mi pregunta es realmente acerca de las mejores prácticas. Necesito algún tipo de estrategia para implementar, tanto en entornos de desarrollo como en entornos de producción. Mi intuición es crear un directorio y almacenar todos mis documentos de diseño allí, luego escribir algún tipo de script de sincronización que cargue cada uno en el sofá (probablemente sobrescribiendo ciegamente lo que ya está allí). ¿Es esta una buena idea?

La documentación para "Writing views in Python" es de 5 oraciones, y realmente solo explica cómo instalar couchpy. En el project's google code site, se menciona un módulo de couchdb.design que parece que podría ayudar, pero no hay documentación (que pueda encontrar). El código fuente de ese módulo indica que hace la mayor parte de lo que me interesa, pero no llega a cargar los archivos. Creo que debería hacer algún tipo de descubrimiento de módulo, pero he oído que no es Pythonic. ¿Consejo?

Editar:

En particular, la idea de almacenar mi mapa/reducir las funciones dentro de los literales de cadena parece completamente hacky. Me gustaría escribir un código python real, en un módulo real, en un paquete real, con pruebas de unidades reales. Periódicamente, me gustaría sincronizar mi paquete "vistas de sofá" con una instancia de couchdb.

Respuesta

3

Aquí hay un enfoque que parece razonable. Primero, clasifico couchdb.design.ViewDefinition. (Comentarios y pydocs removidos por razones de brevedad.)

import couchdb.design 
import inflection 

DESIGN_NAME="version" 

class CurrentVersion(couchdb.design.ViewDefinition): 
    def __init__(self): 

     map_fun = self.__class__.map 

     if hasattr(self.__class__, "reduce"): 
      reduce_fun = self.__class__.reduce 
     else: 
      reduce_fun = None 

     super_args = (DESIGN_NAME, 
         inflection.underscore(self.__class__.__name__), 
         map_fun, 
         reduce_fun, 
         'python') 

     super(CurrentVersion, self).__init__(*super_args) 

    @staticmethod 
    def map(doc): 
     if 'version_key' in doc and 'created_ts' in doc: 
      yield (doc['version_key'], [doc['_id'], doc['created_ts']]) 

    @staticmethod 
    def reduce(keys, values, rereduce): 
     max_index = 0 

     for index, value in enumerate(values): 
      if value[1] > values[max_index][1]: 
       max_index = index 

     return values[max_index] 

Ahora, si quiero sincronizar:

import couchdb.design 
from couchview.version import CurrentVersion 

db = get_couch_db() # omitted for brevity 
couchdb.design.ViewDefinition.sync_many(db, [CurrentVersion()], remove_missing=True) 

Los beneficios de este enfoque son:

  1. Organización. Todos los diseños/vistas existen como módulos/clases (respectivamente) ubicados en un solo paquete.
  2. Código real. Mi editor de texto resaltará la sintaxis. Puedo escribir pruebas unitarias contra mi mapa/reducir funciones.

La subclase ViewDefinition también se puede usar para realizar consultas.

current_version_view = couchview.version.CurrentVersion() 
result = current_version_view(self.db, key=version_key) 

Todavía no está listo para la producción, pero creo que esto es un gran paso adelante en comparación con el almacenamiento de map/reduce funciones dentro de los literales de cadena.

Edit: finalmente escribió un par de blogs mensajes sobre este tema, ya que no pude encontrar otras fuentes de asesoramiento:

Cuestiones relacionadas