def query(self, key_condition: cond.ConditionBase, global_index: Optional[GlobalSecondaryIndex] = None, attributes: Optional[List[str]] = None, consistent: bool = False, limit: Optional[int] = None) -> List[ItemResult]: # pragma: no cover # noqa 501 """Fetch items from the table based on a key condition. Doesn't support pagination. Args: key_condition: The key condition. Eg.: `Key('PK').eq(str(pk)) & Key('SK').begins_with(str(sk))` global_index: The global secondary index to query. Defaults to the primary index. attributes: The attributes to get. Defaults to `SK`. consistent: Whether the read is strongly consistent or not. limit: The maximum number of items to fetch. Defaults to 1000. Returns: The requested items with the entity name prefixes stripped, eg. if the value of an attribute is 'USER#[email protected]', only '*****@*****.**' is returned. Raises: dokklib_db.DatabaseError if there was an error querying the table. """ query_arg = QueryArg(key_condition, global_index=global_index, attributes=attributes, consistent=consistent, limit=limit) return self._query(query_arg)
def _query(self, query_arg: QueryArg) -> List[ItemResult]: args = query_arg.get_kwargs(self.table_name, self.primary_index) with self._dispatch_error(): query_res = self._client.query(**args) all_items = query_res.get('Items', []) while 'LastEvaluatedKey' in query_res: query_res = self._client.query( ExclusiveStartKey=query_res['LastEvaluatedKey'], **args) all_items.extend(query_res.get('Items', [])) return self._normalize_items(all_items)
def query_prefix(self, pk: PartitionKey, sk: PrefixSortKey, global_index: Optional[GlobalSecondaryIndex] = None, attributes: Optional[List[str]] = None, consistent: bool = False, limit: Optional[int] = None) -> List[ItemResult]: """Fetch a items from the table based on a sort key prefix. Doesn't support pagination. Args: pk: The partition key. sk: The sort key prefix. global_index: The global secondary index to query. Defaults to the primary index. attributes: The attributes to get. Defaults to `[self.primary_index.sort_key]` if no `global_index` is provided and `[global_index.sort_key]` if it is provided. consistent: Whether the read is strongly consistent or not. limit: The maximum number of items to fetch. Defaults to 1000. Returns: The requested items with the `PK` and `SK` prefixes stripped. Raises: dokklib_db.DatabaseError if there was an error querying DynamoDB. """ if global_index: pk_name = global_index.partition_key sk_name = global_index.sort_key else: pk_name = self.primary_index.partition_key sk_name = self.primary_index.sort_key if not attributes: attributes = [sk_name] key_condition = cond.Key(pk_name).eq(str(pk)) & \ cond.Key(sk_name).begins_with(str(sk)) query_arg = QueryArg(key_condition, global_index=global_index, attributes=attributes, consistent=consistent, limit=limit) return self._query(query_arg)
def _query(self, query_arg: QueryArg) -> List[ItemResult]: args = query_arg.get_kwargs(self.table_name, self.primary_index) with self._dispatch_error(): query_res = self._client.query(**args) items = query_res.get('Items', []) return self._normalize_items(items)