monasca-agent/monagent/checks/libs/boto/dynamodb2/fields.py

213 lines
4.9 KiB
Python

from boto.dynamodb2.types import STRING
class BaseSchemaField(object):
"""
An abstract class for defining schema fields.
Contains most of the core functionality for the field. Subclasses must
define an ``attr_type`` to pass to DynamoDB.
"""
attr_type = None
def __init__(self, name, data_type=STRING):
"""
Creates a Python schema field, to represent the data to pass to
DynamoDB.
Requires a ``name`` parameter, which should be a string name of the
field.
Optionally accepts a ``data_type`` parameter, which should be a
constant from ``boto.dynamodb2.types``. (Default: ``STRING``)
"""
self.name = name
self.data_type = data_type
def definition(self):
"""
Returns the attribute definition structure DynamoDB expects.
Example::
>>> field.definition()
{
'AttributeName': 'username',
'AttributeType': 'S',
}
"""
return {
'AttributeName': self.name,
'AttributeType': self.data_type,
}
def schema(self):
"""
Returns the schema structure DynamoDB expects.
Example::
>>> field.schema()
{
'AttributeName': 'username',
'KeyType': 'HASH',
}
"""
return {
'AttributeName': self.name,
'KeyType': self.attr_type,
}
class HashKey(BaseSchemaField):
"""
An field representing a hash key.
Example::
>>> from boto.dynamodb2.types import NUMBER
>>> HashKey('username')
>>> HashKey('date_joined', data_type=NUMBER)
"""
attr_type = 'HASH'
class RangeKey(BaseSchemaField):
"""
An field representing a range key.
Example::
>>> from boto.dynamodb2.types import NUMBER
>>> HashKey('username')
>>> HashKey('date_joined', data_type=NUMBER)
"""
attr_type = 'RANGE'
class BaseIndexField(object):
"""
An abstract class for defining schema fields.
Contains most of the core functionality for the field. Subclasses must
define an ``attr_type`` to pass to DynamoDB.
"""
def __init__(self, name, parts):
self.name = name
self.parts = parts
def definition(self):
"""
Returns the attribute definition structure DynamoDB expects.
Example::
>>> index.definition()
{
'AttributeName': 'username',
'AttributeType': 'S',
}
"""
definition = []
for part in self.parts:
definition.append({
'AttributeName': part.name,
'AttributeType': part.data_type,
})
return definition
def schema(self):
"""
Returns the schema structure DynamoDB expects.
Example::
>>> index.schema()
{
'IndexName': 'LastNameIndex',
'KeySchema': [
{
'AttributeName': 'username',
'KeyType': 'HASH',
},
],
'Projection': {
'ProjectionType': 'KEYS_ONLY,
}
}
"""
key_schema = []
for part in self.parts:
key_schema.append(part.schema())
return {
'IndexName': self.name,
'KeySchema': key_schema,
'Projection': {
'ProjectionType': self.projection_type,
}
}
class AllIndex(BaseIndexField):
"""
An index signifying all fields should be in the index.
Example::
>>> AllIndex('MostRecentlyJoined', parts=[
... HashKey('username'),
... RangeKey('date_joined')
... ])
"""
projection_type = 'ALL'
class KeysOnlyIndex(BaseIndexField):
"""
An index signifying only key fields should be in the index.
Example::
>>> KeysOnlyIndex('MostRecentlyJoined', parts=[
... HashKey('username'),
... RangeKey('date_joined')
... ])
"""
projection_type = 'KEYS_ONLY'
class IncludeIndex(BaseIndexField):
"""
An index signifying only certain fields should be in the index.
Example::
>>> IncludeIndex('GenderIndex', parts=[
... HashKey('username'),
... RangeKey('date_joined')
... ], includes=['gender'])
"""
projection_type = 'INCLUDE'
def __init__(self, *args, **kwargs):
self.includes_fields = kwargs.pop('includes', [])
super(IncludeIndex, self).__init__(*args, **kwargs)
def schema(self):
schema_data = super(IncludeIndex, self).schema()
schema_data['Projection']['NonKeyAttributes'] = self.includes_fields
return schema_data