DynamORM API

dynamorm

The base module namespace simply imports DynaModel from dynamorm.model so that you can:

from dynamorm import DynaModel

dynamorm.model

Models represent tables in DynamoDB and define the characteristics of the Dynamo service as well as the Marshmallow schema that is used for validating and marshalling your data.

class dynamorm.model.DynaModel(**raw)

DynaModel is the base class all of your models will extend from. This model definition encapsulates the parameters used to create and manage the table as well as the schema for validating and marshalling data into object attributes. It will also hold any custom business logic you need for your objects.

Your class must define two inner classes that specify the Dynamo Table options and the Schema, respectively.

The Dynamo Table options are defined in a class named Table. See the dynamorm.table module for more information.

The document schema is defined in a class named Schema, which should be filled out exactly as you would fill out any other Marshmallow Schema or Schematics Model.

For example:

# Marshmallow example
import os

from dynamorm import DynaModel

from marshmallow import fields, validate, validates, ValidationError

class Thing(DynaModel):
    class Table:
        name = '{env}-things'.format(env=os.environ.get('ENVIRONMENT', 'dev'))
        hash_key = 'id'
        read = 5
        write = 1

    class Schema:
        id = fields.String(required=True)
        name = fields.String()
        color = fields.String(validate=validate.OneOf(('purple', 'red', 'yellow')))
        compound = fields.Dict(required=True)

        @validates('name')
        def validate_name(self, value):
            # this is a very silly example just to illustrate that you can fill out the
            # inner Schema class just like any other Marshmallow class
            if name.lower() == 'evan':
                raise ValidationError("No Evan's allowed")

    def say_hello(self):
        print("Hello.  {name} here.  My ID is {id} and I'm colored {color}".format(
            id=self.id,
            name=self.name,
            color=self.color
        ))
# Schematics example
import os

from dynamorm import DynaModel

from schematics import types

class Thing(DynaModel):
    class Table:
        name = '{env}-things'.format(env=os.environ.get('ENVIRONMENT', 'dev'))
        hash_key = 'id'
        read = 5
        write = 1

    class Schema:
        id = types.StringType(required=True, max_length=10)
        name = types.StringType()
        color = types.StringType()
        compound = types.DictType(types.IntType, required=True)

    def say_hello(self):
        print("Hello.  {name} here.  My ID is {id} and I'm colored {color}".format(
            id=self.id,
            name=self.name,
            color=self.color
        ))
class dynamorm.model.DynaModel(**raw)

DynaModel is the base class all of your models will extend from. This model definition encapsulates the parameters used to create and manage the table as well as the schema for validating and marshalling data into object attributes. It will also hold any custom business logic you need for your objects.

Your class must define two inner classes that specify the Dynamo Table options and the Schema, respectively.

The Dynamo Table options are defined in a class named Table. See the dynamorm.table module for more information.

The document schema is defined in a class named Schema, which should be filled out exactly as you would fill out any other Marshmallow Schema or Schematics Model.

For example:

# Marshmallow example
import os

from dynamorm import DynaModel

from marshmallow import fields, validate, validates, ValidationError

class Thing(DynaModel):
    class Table:
        name = '{env}-things'.format(env=os.environ.get('ENVIRONMENT', 'dev'))
        hash_key = 'id'
        read = 5
        write = 1

    class Schema:
        id = fields.String(required=True)
        name = fields.String()
        color = fields.String(validate=validate.OneOf(('purple', 'red', 'yellow')))
        compound = fields.Dict(required=True)

        @validates('name')
        def validate_name(self, value):
            # this is a very silly example just to illustrate that you can fill out the
            # inner Schema class just like any other Marshmallow class
            if name.lower() == 'evan':
                raise ValidationError("No Evan's allowed")

    def say_hello(self):
        print("Hello.  {name} here.  My ID is {id} and I'm colored {color}".format(
            id=self.id,
            name=self.name,
            color=self.color
        ))
# Schematics example
import os

from dynamorm import DynaModel

from schematics import types

class Thing(DynaModel):
    class Table:
        name = '{env}-things'.format(env=os.environ.get('ENVIRONMENT', 'dev'))
        hash_key = 'id'
        read = 5
        write = 1

    class Schema:
        id = types.StringType(required=True, max_length=10)
        name = types.StringType()
        color = types.StringType()
        compound = types.DictType(types.IntType, required=True)

    def say_hello(self):
        print("Hello.  {name} here.  My ID is {id} and I'm colored {color}".format(
            id=self.id,
            name=self.name,
            color=self.color
        ))
classmethod get(consistent=False, **kwargs)

Get an item from the table

Example:

Thing.get(hash_key="three")
Parameters:
  • consistent (bool) – If set to True the get will be a consistent read
  • **kwargs – You must supply your hash key, and range key if used, with the values to get
classmethod new_from_raw(raw)

Return a new instance of this model from a raw (dict) of data that is loaded by our Schema

Parameters:raw (dict) – The attributes to use when creating the instance
classmethod put(item, **kwargs)

Put a single item into the table for this model

The attributes on the item go through validation, so this may raise ValidationError.

Parameters:
  • item (dict) – The item to put into the table
  • **kwargs – All other kwargs are passed through to the put method on the table
classmethod put_batch(*items, **batch_kwargs)

Put one or more items into the table

Parameters:
  • *items – The items to put into the table
  • **kwargs – All other kwargs are passed through to the put_batch method on the table

Example:

Thing.put_batch(
    {"hash_key": "one"},
    {"hash_key": "two"},
    {"hash_key": "three"},
)
classmethod put_unique(item, **kwargs)

Put a single item into the table for this model, with a unique attribute constraint on the hash key

Parameters:
  • item (dict) – The item to put into the table
  • **kwargs – All other kwargs are passed through to the put_unique method on the table
classmethod query(query_kwargs=None, **kwargs)

Execute a query on our table based on our keys

You supply the key(s) to query based on as keyword arguments:

Thing.query(foo="Mr. Foo")

By default the eq condition is used. If you wish to use any of the other valid conditions for keys use a double underscore syntax following the key name. For example:

Thing.query(foo__begins_with="Mr.")
Parameters:
  • query_kwargs (dict) – Extra parameters that should be passed through to the Table query function
  • **kwargs – The key(s) and value(s) to query based on
save(**kwargs)

Save this instance to the table

The attributes on the item go through validation, so this may raise ValidationError.

classmethod scan(scan_kwargs=None, **kwargs)

Execute a scan on our table

You supply the attr(s) to query based on as keyword arguments:

Thing.scan(age=10)

By default the eq condition is used. If you wish to use any of the other valid conditions for attrs use a double underscore syntax following the key name. For example:

Thing.scan(age__lte=10)

Accessing nested attributes also uses the double underscore syntax:

Thing.scan(address__state="CA")
Thing.scan(address__state__begins_with="C")

This returns a generator, which will continue to yield items until all matching the scan are produced, abstracting away pagination. More information on scan pagination: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.Pagination

Parameters:
  • scan_kwargs (dict) – Extra parameters that should be passed through to the Table scan function
  • **kwargs – The key(s) and value(s) to filter based on
class dynamorm.model.DynaModelMeta

DynaModelMeta is a metaclass for the DynaModel class that transforms our Table and Schema classes

Since we can inspect the data we need to build the full data structures needed for working with tables and indexes users can define for more concise and readable table definitions that we transform into the final. To allow for a more concise definition of DynaModels we do not require that users define their inner Schema class as extending from the Schema. Instead, when the class is being defined we take the inner Schema and transform it into a new class named <Name>Schema, extending from Schema. For example, on a model named Foo the resulting Foo.Schema object would be an instance of a class named FooSchema, rather than a class named Schema

dynamorm.table

The inner Table class on DynaModel definitions becomes an instance of our dynamorm.table.DynamoTable3 class.

The attributes you define on your inner Table class map to underlying boto data structures. This mapping is expressed through the following data model:

Attribute Required Type Description
name True str The name of the table, as stored in Dynamo.
hash_key True str The name of the field to use as the hash key. It must exist in the schema.
range_key False str The name of the field to use as the range_key, if one is used. It must exist in the schema.
read True int The provisioned read throughput.
write True int The provisioned write throughput.
class dynamorm.table.DynamoTable3(schema)

Represents a Table object in the Boto3 DynamoDB API

This is built in such a way that in the future, when Amazon releases future boto versions, a new DynamoTable class can be authored that implements the same methods but maps through to the new semantics.

attribute_definitions

Return an appropriate AttributeDefinitions, based on our key attributes and the schema object

create(wait=True)

Create a new table based on our attributes

Parameters:wait (bool) – If set to True, the default, this call will block until the table is created
delete(wait=True)

Delete this existing table

Parameters:wait (bool) – If set to True, the default, this call will block until the table is deleted
exists

Return True or False based on the existance of this tables name in our resource

classmethod get_resource(**kwargs)

Return the boto3 dynamodb resource, create it if it doesn’t exist

The resource is stored globally on the DynamoTable3 class and is shared between all models. To influence the connection parameters you just need to call get_resource on any model with the correct kwargs BEFORE you use any of the models.

classmethod get_table(name)

Return the boto3 Table object for this model, create it if it doesn’t exist

The Table is stored on the class for each model, so it is shared between all instances of a given model.

key_schema

Return an appropriate KeySchema, based on our key attributes and the schema object

provisioned_throughput

Return an appropriate ProvisionedThroughput, based on our attributes

put(item, **kwargs)

Put a singular item into the table

Parameters:
  • item (dict) – The data to put into the table
  • **kwargs – All other keyword arguments are passed through to the DynamoDB Table put_item function.
resource

Return the boto3 resource

table

Return the boto3 table

dynamorm.table.remove_nones(in_dict)

Recursively remove keys with a value of None from the in_dict collection