Getting started with Dynamodb-mapper

Setup Dynamodb-mapper

Installation

$ pip install dynamodb-mapper

Set you Amazon’s API credential in ~/.boto

[Credentials]
aws_access_key_id = <your access key>
aws_secret_access_key = <your secret key>

For advance configuration, please see the official Boto documentation.

Example data: DoomMap

We want a DoomMap to be part of an episode. In our schema, the episodes are identified by an integer ID, this is the hash_key. We also want our episodes to have multiple maps also identified by an integer. This map id is the range_key. range_key allows to logically group items that belongs to a same group.

Our maps also have an name and a set of cheats codes. In DynamoDB, all strings are stored as unicode hence the type. Lastly, we want each maps to recognize by __defaults__ the famous “Konami” cheat code.

DoomMap Model

Start by defining the document structure.

from dynamodb_mapper.model import DynamoDBModel


class DoomMap(DynamoDBModel):
    __table__ = u"doom_map"
    __hash_key__ = u"episode"
    __range_key__ = u"map"
    __schema__ = {
        u"episode": int,
        u"map": int,
        u"name": unicode,
        u"cheats": set,
    }
    __defaults__ = {
        u"cheats": set([u"Konami"]),
    }

All class attributes of the form __attr__ are used to configure the mapper. Note that they are defined on the class level. Any accidental override in the instances will be ignored.

  • __table__ Table name in DynamoDB

  • __hash_key__ Name of the the hash key field

  • __range_key__ Name of the (optional) range key field

  • __schema__ Dict mapping of {"field_name": type}. Must at least contain

    the keys

  • __defaults__ Define an optional default value for each field used by __init__

For more informations on the models and defaults, please see the data models section of this manual.

Initial Table creation

Unlike MongoDB, table creation must be done explicitly. At the moment create_table(), is the only case where you’d want to directly use the ConnectionBorg class.

conn = ConnectionBorg()
conn.create_table(DoomMap, 10, 10, wait_for_active=True)

When creating a table with, you must specify the model class and the desired R/W throughput that is to say the peek number of request per seconds you expect for you application. For more information, please see Amazon’s official documentation.

Default behavior is to create the tables asynchronously but you may explicitly ask for synchronous creation with wait_for_active=True. Please note that only 10 tables may be in CREATING simultaneously.

Example Usage

First, create and save() new map in episode 1 and call it “Hangar”. Let’s also register a couple a cheats.

e1m1 = DoomMap()
e1m1.episode = 1
e1m1.map = 1
e1m1.name = u"Hangar"
e1m1.cheats = set([u"idkfa", u"iddqd", u"idclip"])
e1m1.save()

It is now possible to get() it from the database using a conpound index that is to say, both a hash_key and a range_key. By default, get uses “eventual consistence” for data access but it is possible to ask for strongly consistent data using consistent_read=True.

# Later on, retrieve that same object from the DB...
e1m1 = DoomMap.get(1, 1)

What if I want to get all the maps in a given episode? This is the purpose of the query() methode which also allows to filter the results based on the range_key value.

# query all maps of episode 1
e1_maps = DoomMap.query(hash_key=1)

# query all maps of episode 1 with 'map' hash_key > 5
from boto.dynamodb.condition import GT
e1_maps_after_5 = DoomMap.query(
    hash_key=1,
    range_key_condition=GT(5))

Dynamodb-mapper offers much more usage tools like scan() and delete(), Transaction support...