Tame the Snake to Sit on the Couch

A while ago I came across an aritcle that talked about using python with couchdb. Since I'm interested in learning about the whole NoSQL movement and am trying to understand where this new style of database server fits in the schema (sorry, I couldn't resist) of things I decided to spend a little time getting to know CouchDB better.

The system that I build this script on, tested with, and designed for is Ubuntu (I'm running 10.10 if anyone cares to know). Although I installed CouchDB through apt-get, I decided to get couchdb-python through easy-install. I did this because the website documentation for couchdb-python is written for the most recent version, and the apt-get version is a little out of date.

So after you've installed Couchdb and couchdb-python you can now run the script below:

  1. #!/usr/bin/python
  2. '''
  3. Simple script to start playing with the couchdb python package.
  4. '''
  6. import os
  7. import subprocess
  8. import re
  9. import sys
  10. import couchdb
  11. from couchdb.mapping import TextField, ListField, DictField
  13. class System(couchdb.Document):
  14. _id = TextField()
  15. _rev= TextField()
  16. uname = ListField(TextField())
  17. packages = DictField()
  19. def get_packages():
  20. '''
  21. gather all of the packages on the system, and return a dictionary with
  22. the package name as the key, and the version as the value.
  23. '''
  24. process = subprocess.Popen("dpkg-query -W -f='${Package} ${Version}\n'", stdout=subprocess.PIPE, shell=True)
  25. (proc, error) = process.communicate()
  26. sys.stdout.flush()
  28. if error:
  29. print(error)
  30. sys.exit(1)
  32. proc_dict = {}
  33. for x in proc.splitlines():
  34. m = re.search('(?P<package>\S+)\W(?P<version>\S+)', x)
  35. proc_dict[m.group('package')] = m.group('version')
  37. return proc_dict
  39. def uname_list():
  40. '''
  41. Generate a list based on the data from uname, excluding the
  42. system's name.
  43. '''
  44. l = []
  45. l.append(os.uname()[0])
  46. for x in os.uname()[2:]:
  47. l.append(x)
  49. return l
  51. if __name__ == "__main__":
  52. box_name = os.uname()[1]
  53. # When not using any arguments, defaults to localhost
  54. server = couchdb.client.Server()
  56. # Test to see if the db exists, create if it doesn't
  57. try:
  58. db = server['sys_info']
  59. except couchdb.http.ResourceNotFound:
  60. db = server.create('sys_info')
  62. # test to see if the computer already exists in the db
  63. try:
  64. rev = db[box_name].rev
  65. db.update([System( _id = box_name, _rev = rev,
  66. uname = uname_list(), packages = get_packages())])
  67. except couchdb.http.ResourceNotFound:
  68. db.save(System(_id = box_name, uname = uname_list(),
  69. packages = get_packages()))

If the script ran without errors then you should be able to this URL and see your computers name as well a value of rev:1 – “some string of characters”. If you click on your computer's name, you'll see all the information the put inserted into the database. What you should see is the “_id” field which will contain the computer's name. A “_rev” field which will say the current revision number for this page. A list of all the packages installed on the system... in no particular order. Finally the output of uname, minus the computer name.
If the script did return some errors, what please make sure that you have module initialization arugments correct (line 54). Couchdb-python uses the defaults if there are no arguments, so in this case the module is going to localhost for the host and the admin account, which has no password. Yes, I know this is really unsafe but I'm just playing with things right now.

One of the things I feel worth pointing out in the System class, in order to create a ListField for CouchDB you must specify what the ListField will contain. In this case (line 16) I am filling the ListField with TextFields. Or in Python speak, filling the list with strings.

I'm surprisingly fascinated with CouchDB... though I'm really hard pressed to say why. At this moment I want to modify my tweet_dump project to use CouchDB. So expect to see that series continued in a little while.

One last thing, for those of you who celebrate it, Happy Thanksgiving!

Nice post

Hi Bryce,

Nice post. I'm the maintainer of couchdb-python, so I just wanted to speak up and say that it's nice to see some attention for CouchDB in the Python community (I picked up your post from Planet Python). Anyway, if you have any issues with couchdb-python, be sure to email our mailing list (at google groups)!

Hope you like relaxing on the Couch,


Hey Dirkjan, Thanks for the

Hey Dirkjan,

Thanks for the post as well as the compliment. And thank you for your hard work in writing and maintaining couchdb-python. It may not mean much but I appreciate it.

If you made it this far down into the article, hopefully you liked it enough to share it with your friends. Thanks if you do, I appreciate it.

Bookmark and Share