You are on page 1of 42

Relax your project

with CouchDB
Benoît Chesneau
26/05/2010 - djangocon berlin
Wednesday, May 26, 2010
• Why using a “NoSQL” solution ?

• CouchDB ?

• CouchDBKit: CouchDB & Django

Wednesday, May 26, 2010


Why i’m here

• CouchDB developer
• Maintainer of CouchDBkit,
Couchbeam, Couchapp ,
couchdbproxy, ...
• benoitc@apache.org

Wednesday, May 26, 2010


Why NOSQL ?

• We don’t need “scalability” sometimes


• Most of DB size < 300 GB (2 GB)
• All my data could be on a machine
(comcast)
• Often, DB requests are fast enough

Wednesday, May 26, 2010


Agile

• Different kinds of data


• Easy denormalisation
• Migrate your data easily
• Keep your data safe
• Flexibility, Simplicity

Wednesday, May 26, 2010


KEEP YOUR DATA SAFE

Wednesday, May 26, 2010


Ex. Shop

Order Customer Delivery

Item Item

Wednesday, May 26, 2010


CouchDB

• Oriented Document Database


• REST
• Map/Reduce (M/R)
• Append-Only
• Javascript/Erlang
• Replication

Wednesday, May 26, 2010


Document Oriented?

• Schema-less
• JSON
• Attachments

Wednesday, May 26, 2010


JSON DOCUMENT

{
"_id": "foo",
"_rev": "1-....",
"url": "http://apache.couchdb.org",
"vote": 1
}

Wednesday, May 26, 2010


Futon
Wednesday, May 26, 2010
Map/Reduce ?

• Map (M) : Collect a list of values


associated to a key
• Return a K-V list
• Reduce (R) : Reduce a list of K-V in one
list of values
• Rereduce

Wednesday, May 26, 2010


MAP.JS

function(doc) {
if (doc.url && doc.vote)
emit(doc.url, doc.vote);
}

Wednesday, May 26, 2010


{
"total_rows": 3,
"offset": 0,
"rows": [{
"id": "15c92051cc81d564db4337a05087bc8d",
"key": "http://apache.couchdb.org",
"value": 1
},
{
"id": "fa9658810d25cac893748e4ff15e7253",
"key": "http://apache.couchdb.org",
"value": 1
},
{
"id": "1fa0c68d8455196507b8b01645e65186",
"key": "http://mysql.com",
"value": -1
}]
}

Wednesday, May 26, 2010


REDUCE.JS
function(keys, values, rereduce) {
return sum(values);
}

{
"rows": [
{
"key": "http://mysql.com",
"value": -1
},
{
"key": "http://apache.couchdb.org",
"value": 2
}
]
}
Wednesday, May 26, 2010
Réplicatuon

• Incremental
• Master-Master
• Continue or when needed

Wednesday, May 26, 2010


Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
Wednesday, May 26, 2010
More

• Sharding: yes
• couchdb-lounge, cloudant, yours
• Geocouch. Full r-tree

Wednesday, May 26, 2010


couchdbkit

Wednesday, May 26, 2010


CouchDBKit

• CouchDB Python framework


• support CouchDB 0.10.2 & 0.11.0
• Simple client
• Object Document Mapping (“ODM”)
• Django extension
• Couchapp compatible

Wednesday, May 26, 2010


client

from couchdbkit
import Server

s = Server("http://127.0.0.1:5984")
db = s["mydb"]
doc = { "a": 1 }
db.save_doc(doc)
doc["b"] = 2
db.save(doc)

doc1 = db.get(doc['_id'])

Wednesday, May 26, 2010


Other features

• db.views
• from couchdbkit.loaders import
FileSystemDocsLoader

Wednesday, May 26, 2010


from couchdbkit.loaders import FileSystemDocsLoader

loader = FileSystemDocsLoader('/path/to/example/_design')
loader.sync(db, verbose=True)

Wednesday, May 26, 2010


Object Document
Mapping
from couchdbkit.schema import *

class MyDoc(Document):
a = IntegerProperty()
contain(db, MyDoc)

doc = MyDoc()
doc.a = 1
doc.save()

doc.b = 2
doc.save()

doc1 = MyDoc.get(doc._id)

Wednesday, May 26, 2010


Django Extension

• from couchdbkt.ext.django import *


• Django helper
• manage.py syncdb
• DocumentForm

Wednesday, May 26, 2010


settings.py
...

COUCHDB_DATABASES = (
('djangoapp.greeting', 'http://127.0.0.1:5984/greeting'),
)

...

INSTALLED_APPS = (
...
'couchdbkit.ext.django',
'djangoapp.greeting',
...
)

Wednesday, May 26, 2010


models.py

from datetime
import datetime
from couchdbkit.ext.django.schema import *

class Greeting(Document):
author = StringProperty()
content = StringProperty(required=True)
date = DateTimeProperty(default=datetime.utcnow)

Wednesday, May 26, 2010


forms.py

class GreetingForm(DocumentForm):
class Meta:
document = Greeting

Wednesday, May 26, 2010


views.py
def home(request):
greet = None
if request.POST:
form = GreetingForm(request.POST)
if form.is_valid():
greet = form.save()
else:
form = GreetingForm()
greetings = Greeting.view("greeting/all")
return render("home.html", {
"form": form,
"greet": greet,
"greetings": greetings
}, context_instance=RequestContext(request))

Wednesday, May 26, 2010


0.5

• New mapping (Objects with


annotations)
• Admin integration
• Possibility to attach design doc to some
objects
• MultiDB & DB backend in extension
• Eventlet support

Wednesday, May 26, 2010


Wednesday, May 26, 2010
Liens

• http://apache.couchdb.org
• http://couchdbkit.org

Wednesday, May 26, 2010


Questions

Wednesday, May 26, 2010


@benoitc

Wednesday, May 26, 2010


Cette création est mise à disposition selon le Contrat
Paternité 2.0 France disponible en ligne http://
creativecommons.org/licenses/by/2.0/fr/ ou par courrier
postal à Creative Commons, 171 Second Street, Suite
300, San Francisco, California 94105, USA.

Wednesday, May 26, 2010

You might also like