1. Relaxez-vous

    avec CouchDB et Python

    Benoît Chesneau <benoitc@e-engura.com>

  2. Oubliez SQL

    • SQL est le choix le plus souvent pris pour gerer une grand nombre de donné
    • Reste le fs, les bases clés/valeurs ...
  3. Gérer des données c'est ...

    • ACID : Atomicité, Cohérence, Isolation, Durée(Permanence)
    • Aujourd'hui les données ne sont pas figées, elles évoluent, ne plus penser en terme de table mais en terme de schema évolutif
    • Une fois les données sauvées, ce qui importe c'est de les voir et de la manière la plus souple possible. Reproduire la feuille de papier
    • Les partager: clusters, offline pour les commerciaux par ex, update des données en cours de route, synchronisation ...
  4. Bienvenue Apache CouchDB

  5. Documents

  6. Exemple de document :

    
    {
      _id:”098F6BCD4621D373CADE4E832627B4F6”,
      _rev: 4134847,
      “username”: “benoitc”,
      “email”: “benoitc@e-engura.com“,
      “password“: “da39a3ee5e6b4b0d3255bfef95601890afd80709“
      “visites”: 10,
      “created“": “2008-05-15T23:31:19Z“
    }
    
  7. Une api REST

  8. Vues & Map/Reduce

  9. Localisons les documents / tags

    Clé Valeur
    family 1
    amis 1
    amis 1
    travail 1
    travail 1
    impact 1
  10. Vue : localisons les tags (Map)

  11. Réduisons les tags

    Clé Valeur
    famille 1
    amis 1
    amis 1
    travail 1
    travail 1
    impact 1
    Clé Valeur
    famille 1
    amis 2
    travail 2
    impact 1

  12. Vue pour réduire les tags:

  13. Couchdb en résumé

    Un système robuste de stockage de données Réplication
    Une API REST dialoguant en utilisant Json Map/Reduce
    Un système de vue en Javascript (ou en python !) développé en Erlang/OTP
    Recherche fulltext Ajoutez votre fonctionnalité ici, c'est opensource!
  14. Architecture CouchDB

  15. Démo

  16. CouchDB et python

  17. 2 clients python et 1 boîte à outils

  18. couchdb-python

  19. un client orienté autour de 5 objets

  20. l'exemple de friendpaste

  21. accès à la base de donnée

    # init views and create db
    couchdb_server = Server(settings.SERVER_URI)
    try:
        self.db = couchdb_server.create(settings.DATABASE_NAME)
    except ResourceConflict:
        self.db = couchdb_server[settings.DATABASE_NAME]
    
  22. le document Paste et sa révsion

    Un objet héritant Document:

    class Snippet(Document):
        title=TextField()
        type=TextField(default='snippet')
        parent=TextField(default='')
        revid = TextField()
        snippet=TextField()
        language=TextField()
        created = DateTimeField()
        updated = DateTimeField()
    
        def store(self, db):
            """override store procedure to generate small id""""
    
    

  23. Sauver le document

    On sauve le document en passant à la fonction store la base où il doit être sauvé :

    s = Snippet(
                        title=d.get('title', ""),
                        snippet=d.get('snippet'),
                        language=d.get('language', 'text')
                )
    s.store(local.application.db)
    

  24. Récupérer les révisions du document

  25. Récupérer la vue

    def _get_snippet_revisions(id): 
        try:
            r = local.application.db.view('_view/paste/by_id', startkey=[str(id)], endkey=[str(id),10])
        except:
            raise NotFound
        results = [r for r in res.__iter__()]
        return results
    
    def get_snippet(id, rev=None):
        revisions = {}
        res = _get_snippet_revisions(id)
        if len(res) > 1:
            revisions = res[1:]
            revisions.sort(lambda a,b: cmp(a.key[1], b.key[1]))
            revisions.reverse()
    
  26. Démo

  27. Paisley

  28. Exemple de Paisley

    import paisley
    from twisted.internet import reactor, defer
    from twisted.web import client
    client.HTTPClientFactory.noisy = False
    
    def test():
        foo = paisley.CouchDB('localhost')
        d = foo.createDB('mydb')
        wfd = defer.waitForDeferred(d)
        yield wfd
        print wfd.getResult()
        d = foo.saveDoc('mydb', '{"value":{"Subject":"I like Planktion"}}', 'mydoc')
        wfd = defer.waitForDeferred(d)
        yield wfd
        print wfd.getResult()
        reactor.stop()
    test = defer.deferredGenerator(test)
    
    if __name__ == "__main__":
        reactor.callWhenRunning(test)
        reactor.run()
    
  29. EnkiCMS opensource engine

  30. EnkiCMS en bref

  31. Questions

  32. Quelques liens