Viewing file: fields.py (8.1 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
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 indexes.
Contains most of the core functionality for the index. Subclasses must define a ``projection_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
class GlobalBaseIndexField(BaseIndexField): """ An abstract class for defining global indexes.
Contains most of the core functionality for the index. Subclasses must define a ``projection_type`` to pass to DynamoDB. """ throughput = { 'read': 5, 'write': 5, }
def __init__(self, *args, **kwargs): throughput = kwargs.pop('throughput', None)
if throughput is not None: self.throughput = throughput
super(GlobalBaseIndexField, self).__init__(*args, **kwargs)
def schema(self): """ Returns the schema structure DynamoDB expects.
Example::
>>> index.schema() { 'IndexName': 'LastNameIndex', 'KeySchema': [ { 'AttributeName': 'username', 'KeyType': 'HASH', }, ], 'Projection': { 'ProjectionType': 'KEYS_ONLY', }, 'ProvisionedThroughput': { 'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5 } }
""" schema_data = super(GlobalBaseIndexField, self).schema() schema_data['ProvisionedThroughput'] = { 'ReadCapacityUnits': int(self.throughput['read']), 'WriteCapacityUnits': int(self.throughput['write']), } return schema_data
class GlobalAllIndex(GlobalBaseIndexField): """ An index signifying all fields should be in the index.
Example::
>>> GlobalAllIndex('MostRecentlyJoined', parts=[ ... HashKey('username'), ... RangeKey('date_joined') ... ], ... throughput={ ... 'read': 2, ... 'write': 1, ... })
""" projection_type = 'ALL'
class GlobalKeysOnlyIndex(GlobalBaseIndexField): """ An index signifying only key fields should be in the index.
Example::
>>> GlobalKeysOnlyIndex('MostRecentlyJoined', parts=[ ... HashKey('username'), ... RangeKey('date_joined') ... ], ... throughput={ ... 'read': 2, ... 'write': 1, ... })
""" projection_type = 'KEYS_ONLY'
class GlobalIncludeIndex(GlobalBaseIndexField, IncludeIndex): """ An index signifying only certain fields should be in the index.
Example::
>>> GlobalIncludeIndex('GenderIndex', parts=[ ... HashKey('username'), ... RangeKey('date_joined') ... ], ... includes=['gender'], ... throughput={ ... 'read': 2, ... 'write': 1, ... })
""" projection_type = 'INCLUDE'
def __init__(self, *args, **kwargs): throughput = kwargs.pop('throughput', None) IncludeIndex.__init__(self, *args, **kwargs) if throughput: kwargs['throughput'] = throughput GlobalBaseIndexField.__init__(self, *args, **kwargs)
def schema(self): # Pick up the includes. schema_data = IncludeIndex.schema(self) # Also the throughput. schema_data.update(GlobalBaseIndexField.schema(self)) return schema_data
|