Author: I (iroiso at live dot com)
License: Apache License 2.0
© 2011, June inc.
Homer is an intuitive and pragmatic python based object non-relational mapper for Apache Cassandra with a beautiful API.
To install homer download the latest build from Github
Download the latest build by cloning master repository
$ git clone git://github.com/junery/homer.git
$ cd homer
$ sudo python setup.py install
This example walks you through creating a simple model and persisting it to cassandra. We assume you've used cassandra before; If you haven't there are plenty of helpful resources on the Apache Cassandra Project Page that'll get you started.
So here we go:
# Relevant imports. from homer import UUID, String, URL, Integer from homer import Model, Level ''' Homer models are python classes that extend the homer 'Model' super class. Let's create a model for storing profile information in cassandra. ''' class Profile(Model): id = UUID() name = String(required=True) fullname = String(indexed=True) age = Integer(indexed=True) link = URL("http://rafiki.me/user/new", indexed=True) ''' Some simple things to note: 1. All models must have an 'id' property which provides the ID for the model when it is stored in Cassandra. 2. The String and URL properties (more in the homer.core.commons package) are just common descriptors for data conversion and validation; adding: `indexed=True` : Creates an index on the name and link property of the Profile class which would allow us to query against them later. `required=True` : Tells Homer to require this property before the Model can be stored in the datastore. You can create new models like ordinary python classes, like this: ''' person = Profile(name='Yoda', link='http://faceboook.com/yoda', fullname="Master Yoda") ''' Then you can save the person to cassandra by calling person.save(), this stores the profile you created with the default consistency level which is ConsistencyLevel.ONE ''' person.save() ''' Notice all the things you aren't doing: 1. You aren't creating any keyspaces 2. You aren't creating any column families. 3. Serialization and Deserialization 4. You aren't creating any thrift connections or doing any connection pooling or any other low level stuff. Nice huh :), Send me some coffee :D Homer will automatically create a Column Family named 'Profile' in a keyspace named 'June' when you save an instance of your model for the first time (ofcourse you can customize things); It also handles connection pooling, batch updates, and does a lot of cool things under the hood for you. Homer's behavior is very configurable, and simple to configure. More on this in later documentation. ''' # You can also save stuff with a different consistency level. another = Profile(name='Iroiso', link='http://facebook.com/iroiso', age=10) with Level.Quorum: #You can also use Level.One, Level.Two, or Level.All another.save() # Reading from Cassandra with Homer is Simple. found = Profile.read('Yoda') assert person == found # Want stronger consistency when you read or write? you can use the 'with Level.All' clause too! with Level.All: found = Profile.read('Yoda') assert person == found ''' You can also query the indexes on cassandra with homer using the idiom: ''' iter = Profile.query(fullname="Master Yoda") # Returns a iterable generator that yields Profile instances found = Profile.query(fullname="Master Yoda").one() # Retreive the first result. assert found == person ''' and you can count all your models using Profile.count (which also takes parameters and filters); ''' count = Profile.count() # To count all the Profile models, or count = Profile.count(fullname="Master Yoda") ''' Finally you can retrieve all your models using Profile.all() which returns an generator object you can iterate over, like so: ''' for person in Profile.all(): print person.name ''' If you want more fine grained queries, you can go crazy like. ''' query = Profile.objects.where(age=LTE(10), name='Yoda').orderby("name", asc=True).limit(10).filter() people = list(query) # forces the 'query' to execute and yield all its results, you can also iterate through 'query' # or fetch just one result by typing query.one(). Explore more options by reading the code.
This is by no means a complete guide. There is still alot of documenting and explaining to do, need more samples? please dive into the Tests Directory to quench your thirst. Any suggestions or improvements? Fork away!
Wanna know about all the other cool things homer does for you behind the scenes? Read all the reasons you should use Homer
Does any of these seem interesting? then maybe you'd like to join us our startup or contribute to Homer. Either ways we'd love to hear from you. Reach out to me here: iroiso at live dot com.
Another pragmatic, beautiful and simple opensource project: "Made with Love in June."