Exemplo n.º 1
0
	def query(cls, hash_key=None, range_key_condition=None,
				request_limit=None, consistent_read=False,
				scan_index_forward=True, **kwargs):
		'''Query under a given hash_key

		:type range_key_condition: dict
		:param range_key_condition: A dict where the key is either
			a scalar value appropriate for the RangeKey in the schema
			of the database or a tuple of such values.  The value-
			associated with this key in the dict will be one of the
			following conditions:

			'EQ'|'LE'|'LT'|'GE'|'GT'|'BEGINS_WITH'|'BETWEEN'

			The only condition which expects or will accept a tuple
			of values is 'BETWEEN', otherwise a scalar value should
			be used as the key in the dict.

		:type request_limit: int
		:param request_limit: The maximum number of items to request from DynamoDB
			in one request. This limit helps with preventing over usage of your
			read quota.

		:type consistent_read: bool
		:param consistent_read: If True, a consistent read
			request is issued.  Otherwise, an eventually consistent
			request is issued.

		:type scan_index_forward: bool
		:param scan_index_forward: Specified forward or backward
			traversal of the index.  Default is forward (True).
		'''

		attempt = 0
		last_error = None
		# Handle Keyword Searches
		if kwargs:
			from decimal import Decimal
			from boto.dynamodb2.table import Table
			tbl = Table(cls._table_name)
			index_name = []
			args = {}
			for arg in kwargs:
				index_name.append(arg)
				args[arg + '__eq'] = kwargs[arg]
			index_name.append('index')
			index_name = '-'.join(index_name)
			for item in tbl.query_2(index=index_name, **args):
				# Convert some values out to simple Python values
				data = {}
				for attr_name in item.keys():
					val = item[attr_name]
					if isinstance(val, Decimal):
						val = int(val)
					if isinstance(val, set):
						val = list(val)
					data[attr_name] = val
				yield cls.from_dict(data)
		else:
			while attempt < MAX_RETRIES:
				try:
					for item in cls.get_table().query(hash_key=hash_key,
						range_key_condition=range_key_condition,
						request_limit=request_limit,
						consistent_read=consistent_read,
						scan_index_forward=scan_index_forward, item_class=cls):
						yield item
					return
				except DynamoDBResponseError, e:
					log.exception('Dynamo Response Error: %s' % e)
					cls._table = None
					attempt += 1
					last_error = e
					time.sleep(attempt ** 2)
				except BotoServerError, e:
					log.error('Boto Server Error: %s' % e)
					cls._table = None
					attempt += 1
					last_error = e
					time.sleep(attempt ** 2)