Deprecate mock_dynamodb2 (#4919)
This commit is contained in:
parent
9dccebc184
commit
07913cfef0
@ -6,7 +6,7 @@ include moto/ec2/resources/instance_types.json
|
||||
include moto/ec2/resources/instance_type_offerings/*/*.json
|
||||
include moto/ec2/resources/amis.json
|
||||
include moto/cognitoidp/resources/*.json
|
||||
include moto/dynamodb2/parsing/reserved_keywords.txt
|
||||
include moto/dynamodb/parsing/reserved_keywords.txt
|
||||
include moto/ssm/resources/*.json
|
||||
include moto/support/resources/*.json
|
||||
recursive-include moto/moto_server *
|
||||
|
@ -16,8 +16,8 @@ dynamodb
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_dynamodb2_behaviour:
|
||||
@mock_dynamodb
|
||||
def test_dynamodb_behaviour:
|
||||
boto3.client("dynamodb")
|
||||
...
|
||||
|
||||
|
@ -53,7 +53,7 @@ mock_batch = lazy_load(".batch", "mock_batch")
|
||||
mock_budgets = lazy_load(".budgets", "mock_budgets")
|
||||
mock_cloudformation = lazy_load(".cloudformation", "mock_cloudformation")
|
||||
mock_cloudfront = lazy_load(".cloudfront", "mock_cloudfront")
|
||||
mock_cloudtrail = lazy_load(".cloudtrail", "mock_cloudtrail", boto3_name="cloudtrail")
|
||||
mock_cloudtrail = lazy_load(".cloudtrail", "mock_cloudtrail")
|
||||
mock_cloudwatch = lazy_load(".cloudwatch", "mock_cloudwatch")
|
||||
mock_codecommit = lazy_load(".codecommit", "mock_codecommit")
|
||||
mock_codepipeline = lazy_load(".codepipeline", "mock_codepipeline")
|
||||
@ -67,9 +67,11 @@ mock_datapipeline = lazy_load(".datapipeline", "mock_datapipeline")
|
||||
mock_datasync = lazy_load(".datasync", "mock_datasync")
|
||||
mock_dax = lazy_load(".dax", "mock_dax")
|
||||
mock_dms = lazy_load(".dms", "mock_dms")
|
||||
mock_ds = lazy_load(".ds", "mock_ds", boto3_name="ds")
|
||||
mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb", warn_repurpose=True)
|
||||
mock_dynamodb2 = lazy_load(".dynamodb2", "mock_dynamodb2", backend="dynamodb_backends2")
|
||||
mock_ds = lazy_load(".ds", "mock_ds")
|
||||
mock_dynamodb = lazy_load(".dynamodb", "mock_dynamodb")
|
||||
mock_dynamodb2 = lazy_load(
|
||||
".dynamodb", "mock_dynamodb", use_instead=("mock_dynamodb2", "mock_dynamodb")
|
||||
)
|
||||
mock_dynamodbstreams = lazy_load(".dynamodbstreams", "mock_dynamodbstreams")
|
||||
mock_elasticbeanstalk = lazy_load(
|
||||
".elasticbeanstalk", "mock_elasticbeanstalk", backend="eb_backends"
|
||||
|
@ -45,7 +45,7 @@ from .utils import (
|
||||
split_layer_arn,
|
||||
)
|
||||
from moto.sqs import sqs_backends
|
||||
from moto.dynamodb2 import dynamodb_backends2
|
||||
from moto.dynamodb import dynamodb_backends
|
||||
from moto.dynamodbstreams import dynamodbstreams_backends
|
||||
from moto.core import ACCOUNT_ID
|
||||
from moto.utilities.docker_utilities import DockerModel, parse_image_ref
|
||||
@ -1259,7 +1259,7 @@ The Docker images used by Moto are taken from the `lambci/lambda`-repo by defaul
|
||||
esm = EventSourceMapping(spec)
|
||||
self._event_source_mappings[esm.uuid] = esm
|
||||
table_name = stream["TableName"]
|
||||
table = dynamodb_backends2[self.region_name].get_table(table_name)
|
||||
table = dynamodb_backends[self.region_name].get_table(table_name)
|
||||
table.lambda_event_source_mappings[esm.function_arn] = esm
|
||||
return esm
|
||||
raise RESTError("ResourceNotFoundException", "Invalid EventSourceArn")
|
||||
|
@ -10,6 +10,7 @@ decorators = [
|
||||
]
|
||||
decorator_functions = [getattr(moto, f) for f in decorators]
|
||||
BACKENDS = {f.boto3_name: (f.name, f.backend) for f in decorator_functions}
|
||||
BACKENDS["dynamodb_v20111205"] = ("dynamodb_v20111205", "dynamodb_backends")
|
||||
BACKENDS["moto_api"] = ("core", "moto_api_backends")
|
||||
BACKENDS["instance_metadata"] = ("instance_metadata", "instance_metadata_backends")
|
||||
BACKENDS["s3bucket_path"] = ("s3", "s3_backends")
|
||||
|
@ -21,7 +21,7 @@ from moto.batch import models # noqa # pylint: disable=all
|
||||
from moto.cloudformation.custom_model import CustomModel
|
||||
from moto.cloudwatch import models # noqa # pylint: disable=all
|
||||
from moto.datapipeline import models # noqa # pylint: disable=all
|
||||
from moto.dynamodb2 import models # noqa # pylint: disable=all
|
||||
from moto.dynamodb import models # noqa # pylint: disable=all
|
||||
from moto.ec2 import models as ec2_models
|
||||
from moto.ecr import models # noqa # pylint: disable=all
|
||||
from moto.ecs import models # noqa # pylint: disable=all
|
||||
|
@ -1,4 +1,5 @@
|
||||
from .models import dynamodb_backend
|
||||
from moto.dynamodb.models import dynamodb_backends
|
||||
from ..core.models import base_decorator
|
||||
|
||||
dynamodb_backends = {"global": dynamodb_backend}
|
||||
mock_dynamodb = dynamodb_backend.decorator
|
||||
dynamodb_backend = dynamodb_backends["us-east-1"]
|
||||
mock_dynamodb = base_decorator(dynamodb_backends)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
from moto.dynamodb2.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
from moto.dynamodb.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
|
||||
|
||||
class InvalidIndexNameError(ValueError):
|
@ -11,9 +11,9 @@ from moto.core import ACCOUNT_ID
|
||||
from moto.core import BaseBackend, BaseModel, CloudFormationModel
|
||||
from moto.core.utils import unix_time, unix_time_millis, BackendDict
|
||||
from moto.core.exceptions import JsonRESTError
|
||||
from moto.dynamodb2.comparisons import get_filter_expression
|
||||
from moto.dynamodb2.comparisons import get_expected
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.comparisons import get_filter_expression
|
||||
from moto.dynamodb.comparisons import get_expected
|
||||
from moto.dynamodb.exceptions import (
|
||||
InvalidIndexNameError,
|
||||
ItemSizeTooLarge,
|
||||
ItemSizeToUpdateTooLarge,
|
||||
@ -26,12 +26,12 @@ from moto.dynamodb2.exceptions import (
|
||||
MultipleTransactionsException,
|
||||
TooManyTransactionsException,
|
||||
)
|
||||
from moto.dynamodb2.models.utilities import bytesize
|
||||
from moto.dynamodb2.models.dynamo_type import DynamoType
|
||||
from moto.dynamodb2.parsing.executors import UpdateExpressionExecutor
|
||||
from moto.dynamodb2.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb2.parsing.validators import UpdateExpressionValidator
|
||||
from moto.dynamodb2.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
from moto.dynamodb.models.utilities import bytesize
|
||||
from moto.dynamodb.models.dynamo_type import DynamoType
|
||||
from moto.dynamodb.parsing.executors import UpdateExpressionExecutor
|
||||
from moto.dynamodb.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb.parsing.validators import UpdateExpressionValidator
|
||||
from moto.dynamodb.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
|
||||
|
||||
class DynamoJsonEncoder(json.JSONEncoder):
|
@ -1,6 +1,6 @@
|
||||
from moto.dynamodb2.comparisons import get_comparison_func
|
||||
from moto.dynamodb2.exceptions import IncorrectDataType
|
||||
from moto.dynamodb2.models.utilities import bytesize
|
||||
from moto.dynamodb.comparisons import get_comparison_func
|
||||
from moto.dynamodb.exceptions import IncorrectDataType
|
||||
from moto.dynamodb.models.utilities import bytesize
|
||||
|
||||
|
||||
class DDBType(object):
|
@ -2,7 +2,7 @@ import abc
|
||||
from abc import abstractmethod
|
||||
from collections import deque
|
||||
|
||||
from moto.dynamodb2.models import DynamoType
|
||||
from moto.dynamodb.models import DynamoType
|
||||
from ..exceptions import TooManyAddClauses
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
from abc import abstractmethod
|
||||
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.exceptions import (
|
||||
IncorrectOperandType,
|
||||
IncorrectDataType,
|
||||
ProvidedKeyDoesNotExist,
|
||||
)
|
||||
from moto.dynamodb2.models import DynamoType
|
||||
from moto.dynamodb2.models.dynamo_type import DDBTypeConversion, DDBType
|
||||
from moto.dynamodb2.parsing.ast_nodes import (
|
||||
from moto.dynamodb.models import DynamoType
|
||||
from moto.dynamodb.models.dynamo_type import DDBTypeConversion, DDBType
|
||||
from moto.dynamodb.parsing.ast_nodes import (
|
||||
UpdateExpressionSetAction,
|
||||
UpdateExpressionDeleteAction,
|
||||
UpdateExpressionRemoveAction,
|
||||
@ -18,7 +18,7 @@ from moto.dynamodb2.parsing.ast_nodes import (
|
||||
ExpressionSelector,
|
||||
ExpressionAttributeName,
|
||||
)
|
||||
from moto.dynamodb2.parsing.validators import ExpressionPathResolver
|
||||
from moto.dynamodb.parsing.validators import ExpressionPathResolver
|
||||
|
||||
|
||||
class NodeExecutor(object):
|
@ -3,7 +3,7 @@ from abc import abstractmethod
|
||||
import abc
|
||||
from collections import deque
|
||||
|
||||
from moto.dynamodb2.parsing.ast_nodes import (
|
||||
from moto.dynamodb.parsing.ast_nodes import (
|
||||
UpdateExpression,
|
||||
UpdateExpressionSetClause,
|
||||
UpdateExpressionSetActions,
|
||||
@ -28,8 +28,8 @@ from moto.dynamodb2.parsing.ast_nodes import (
|
||||
UpdateExpressionDeleteActions,
|
||||
UpdateExpressionDeleteClause,
|
||||
)
|
||||
from moto.dynamodb2.exceptions import InvalidTokenException, InvalidUpdateExpression
|
||||
from moto.dynamodb2.parsing.tokens import Token, ExpressionTokenizer
|
||||
from moto.dynamodb.exceptions import InvalidTokenException, InvalidUpdateExpression
|
||||
from moto.dynamodb.parsing.tokens import Token, ExpressionTokenizer
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
@ -1,6 +1,6 @@
|
||||
import re
|
||||
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.exceptions import (
|
||||
InvalidTokenException,
|
||||
InvalidExpressionAttributeNameKey,
|
||||
)
|
@ -4,7 +4,7 @@ See docstring class Validator below for more details on validation
|
||||
from abc import abstractmethod
|
||||
from copy import deepcopy
|
||||
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.exceptions import (
|
||||
AttributeIsReservedKeyword,
|
||||
ExpressionAttributeValueNotDefined,
|
||||
AttributeDoesNotExist,
|
||||
@ -15,8 +15,8 @@ from moto.dynamodb2.exceptions import (
|
||||
EmptyKeyAttributeException,
|
||||
UpdateHashRangeKeyException,
|
||||
)
|
||||
from moto.dynamodb2.models import DynamoType
|
||||
from moto.dynamodb2.parsing.ast_nodes import (
|
||||
from moto.dynamodb.models import DynamoType
|
||||
from moto.dynamodb.parsing.ast_nodes import (
|
||||
ExpressionAttribute,
|
||||
UpdateExpressionPath,
|
||||
UpdateExpressionSetAction,
|
||||
@ -34,7 +34,7 @@ from moto.dynamodb2.parsing.ast_nodes import (
|
||||
ExpressionValueOperator,
|
||||
ExpressionSelector,
|
||||
)
|
||||
from moto.dynamodb2.parsing.reserved_keywords import ReservedKeywords
|
||||
from moto.dynamodb.parsing.reserved_keywords import ReservedKeywords
|
||||
|
||||
|
||||
class ExpressionAttributeValueProcessor(DepthFirstTraverser):
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
from moto.dynamodb2.models import dynamodb_backends as dynamodb_backends2
|
||||
from ..core.models import base_decorator
|
||||
|
||||
dynamodb_backend2 = dynamodb_backends2["us-east-1"]
|
||||
mock_dynamodb2 = base_decorator(dynamodb_backends2)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
9
moto/dynamodb_v20111205/__init__.py
Normal file
9
moto/dynamodb_v20111205/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
from .models import dynamodb_backend
|
||||
|
||||
"""
|
||||
An older API version of DynamoDB.
|
||||
Please see the corresponding tests (tests/test_dynamodb_v20111205) on how to invoke this API.
|
||||
"""
|
||||
|
||||
dynamodb_backends = {"global": dynamodb_backend}
|
||||
mock_dynamodb = dynamodb_backend.decorator
|
22
moto/dynamodb_v20111205/comparisons.py
Normal file
22
moto/dynamodb_v20111205/comparisons.py
Normal file
@ -0,0 +1,22 @@
|
||||
# TODO add tests for all of these
|
||||
COMPARISON_FUNCS = {
|
||||
"EQ": lambda item_value, test_value: item_value == test_value,
|
||||
"NE": lambda item_value, test_value: item_value != test_value,
|
||||
"LE": lambda item_value, test_value: item_value <= test_value,
|
||||
"LT": lambda item_value, test_value: item_value < test_value,
|
||||
"GE": lambda item_value, test_value: item_value >= test_value,
|
||||
"GT": lambda item_value, test_value: item_value > test_value,
|
||||
"NULL": lambda item_value: item_value is None,
|
||||
"NOT_NULL": lambda item_value: item_value is not None,
|
||||
"CONTAINS": lambda item_value, test_value: test_value in item_value,
|
||||
"NOT_CONTAINS": lambda item_value, test_value: test_value not in item_value,
|
||||
"BEGINS_WITH": lambda item_value, test_value: item_value.startswith(test_value),
|
||||
"IN": lambda item_value, *test_values: item_value in test_values,
|
||||
"BETWEEN": lambda item_value, lower_test_value, upper_test_value: lower_test_value
|
||||
<= item_value
|
||||
<= upper_test_value,
|
||||
}
|
||||
|
||||
|
||||
def get_comparison_func(range_comparison):
|
||||
return COMPARISON_FUNCS.get(range_comparison)
|
294
moto/dynamodb_v20111205/responses.py
Normal file
294
moto/dynamodb_v20111205/responses.py
Normal file
@ -0,0 +1,294 @@
|
||||
import json
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from moto.core.utils import camelcase_to_underscores
|
||||
from .models import dynamodb_backend, dynamo_json_dump
|
||||
|
||||
|
||||
class DynamoHandler(BaseResponse):
|
||||
def get_endpoint_name(self, headers):
|
||||
"""Parses request headers and extracts part od the X-Amz-Target
|
||||
that corresponds to a method of DynamoHandler
|
||||
|
||||
ie: X-Amz-Target: DynamoDB_20111205.ListTables -> ListTables
|
||||
"""
|
||||
# Headers are case-insensitive. Probably a better way to do this.
|
||||
match = headers.get("x-amz-target") or headers.get("X-Amz-Target")
|
||||
if match:
|
||||
return match.split(".")[1]
|
||||
|
||||
def error(self, type_, status=400):
|
||||
return status, self.response_headers, dynamo_json_dump({"__type": type_})
|
||||
|
||||
def call_action(self):
|
||||
self.body = json.loads(self.body or "{}")
|
||||
endpoint = self.get_endpoint_name(self.headers)
|
||||
if endpoint:
|
||||
endpoint = camelcase_to_underscores(endpoint)
|
||||
response = getattr(self, endpoint)()
|
||||
if isinstance(response, str):
|
||||
return 200, self.response_headers, response
|
||||
|
||||
else:
|
||||
status_code, new_headers, response_content = response
|
||||
self.response_headers.update(new_headers)
|
||||
return status_code, self.response_headers, response_content
|
||||
else:
|
||||
return 404, self.response_headers, ""
|
||||
|
||||
def list_tables(self):
|
||||
body = self.body
|
||||
limit = body.get("Limit")
|
||||
if body.get("ExclusiveStartTableName"):
|
||||
last = body.get("ExclusiveStartTableName")
|
||||
start = list(dynamodb_backend.tables.keys()).index(last) + 1
|
||||
else:
|
||||
start = 0
|
||||
all_tables = list(dynamodb_backend.tables.keys())
|
||||
if limit:
|
||||
tables = all_tables[start : start + limit]
|
||||
else:
|
||||
tables = all_tables[start:]
|
||||
response = {"TableNames": tables}
|
||||
if limit and len(all_tables) > start + limit:
|
||||
response["LastEvaluatedTableName"] = tables[-1]
|
||||
return dynamo_json_dump(response)
|
||||
|
||||
def create_table(self):
|
||||
body = self.body
|
||||
name = body["TableName"]
|
||||
|
||||
key_schema = body["KeySchema"]
|
||||
hash_key = key_schema["HashKeyElement"]
|
||||
hash_key_attr = hash_key["AttributeName"]
|
||||
hash_key_type = hash_key["AttributeType"]
|
||||
|
||||
range_key = key_schema.get("RangeKeyElement", {})
|
||||
range_key_attr = range_key.get("AttributeName")
|
||||
range_key_type = range_key.get("AttributeType")
|
||||
|
||||
throughput = body["ProvisionedThroughput"]
|
||||
read_units = throughput["ReadCapacityUnits"]
|
||||
write_units = throughput["WriteCapacityUnits"]
|
||||
|
||||
table = dynamodb_backend.create_table(
|
||||
name,
|
||||
hash_key_attr=hash_key_attr,
|
||||
hash_key_type=hash_key_type,
|
||||
range_key_attr=range_key_attr,
|
||||
range_key_type=range_key_type,
|
||||
read_capacity=int(read_units),
|
||||
write_capacity=int(write_units),
|
||||
)
|
||||
return dynamo_json_dump(table.describe)
|
||||
|
||||
def delete_table(self):
|
||||
name = self.body["TableName"]
|
||||
table = dynamodb_backend.delete_table(name)
|
||||
if table:
|
||||
return dynamo_json_dump(table.describe)
|
||||
else:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
|
||||
def update_table(self):
|
||||
name = self.body["TableName"]
|
||||
throughput = self.body["ProvisionedThroughput"]
|
||||
new_read_units = throughput["ReadCapacityUnits"]
|
||||
new_write_units = throughput["WriteCapacityUnits"]
|
||||
table = dynamodb_backend.update_table_throughput(
|
||||
name, new_read_units, new_write_units
|
||||
)
|
||||
return dynamo_json_dump(table.describe)
|
||||
|
||||
def describe_table(self):
|
||||
name = self.body["TableName"]
|
||||
try:
|
||||
table = dynamodb_backend.tables[name]
|
||||
except KeyError:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
return dynamo_json_dump(table.describe)
|
||||
|
||||
def put_item(self):
|
||||
name = self.body["TableName"]
|
||||
item = self.body["Item"]
|
||||
result = dynamodb_backend.put_item(name, item)
|
||||
if result:
|
||||
item_dict = result.to_json()
|
||||
item_dict["ConsumedCapacityUnits"] = 1
|
||||
return dynamo_json_dump(item_dict)
|
||||
else:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
|
||||
def batch_write_item(self):
|
||||
table_batches = self.body["RequestItems"]
|
||||
|
||||
for table_name, table_requests in table_batches.items():
|
||||
for table_request in table_requests:
|
||||
request_type = list(table_request)[0]
|
||||
request = list(table_request.values())[0]
|
||||
|
||||
if request_type == "PutRequest":
|
||||
item = request["Item"]
|
||||
dynamodb_backend.put_item(table_name, item)
|
||||
elif request_type == "DeleteRequest":
|
||||
key = request["Key"]
|
||||
hash_key = key["HashKeyElement"]
|
||||
range_key = key.get("RangeKeyElement")
|
||||
item = dynamodb_backend.delete_item(table_name, hash_key, range_key)
|
||||
|
||||
response = {
|
||||
"Responses": {
|
||||
"Thread": {"ConsumedCapacityUnits": 1.0},
|
||||
"Reply": {"ConsumedCapacityUnits": 1.0},
|
||||
},
|
||||
"UnprocessedItems": {},
|
||||
}
|
||||
|
||||
return dynamo_json_dump(response)
|
||||
|
||||
def get_item(self):
|
||||
name = self.body["TableName"]
|
||||
key = self.body["Key"]
|
||||
hash_key = key["HashKeyElement"]
|
||||
range_key = key.get("RangeKeyElement")
|
||||
attrs_to_get = self.body.get("AttributesToGet")
|
||||
try:
|
||||
item = dynamodb_backend.get_item(name, hash_key, range_key)
|
||||
except ValueError:
|
||||
er = "com.amazon.coral.validate#ValidationException"
|
||||
return self.error(er, status=400)
|
||||
if item:
|
||||
item_dict = item.describe_attrs(attrs_to_get)
|
||||
item_dict["ConsumedCapacityUnits"] = 0.5
|
||||
return dynamo_json_dump(item_dict)
|
||||
else:
|
||||
# Item not found
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er, status=404)
|
||||
|
||||
def batch_get_item(self):
|
||||
table_batches = self.body["RequestItems"]
|
||||
|
||||
results = {"Responses": {"UnprocessedKeys": {}}}
|
||||
|
||||
for table_name, table_request in table_batches.items():
|
||||
items = []
|
||||
keys = table_request["Keys"]
|
||||
attributes_to_get = table_request.get("AttributesToGet")
|
||||
for key in keys:
|
||||
hash_key = key["HashKeyElement"]
|
||||
range_key = key.get("RangeKeyElement")
|
||||
item = dynamodb_backend.get_item(table_name, hash_key, range_key)
|
||||
if item:
|
||||
item_describe = item.describe_attrs(attributes_to_get)
|
||||
items.append(item_describe)
|
||||
results["Responses"][table_name] = {
|
||||
"Items": items,
|
||||
"ConsumedCapacityUnits": 1,
|
||||
}
|
||||
return dynamo_json_dump(results)
|
||||
|
||||
def query(self):
|
||||
name = self.body["TableName"]
|
||||
hash_key = self.body["HashKeyValue"]
|
||||
range_condition = self.body.get("RangeKeyCondition")
|
||||
if range_condition:
|
||||
range_comparison = range_condition["ComparisonOperator"]
|
||||
range_values = range_condition["AttributeValueList"]
|
||||
else:
|
||||
range_comparison = None
|
||||
range_values = []
|
||||
|
||||
items, _ = dynamodb_backend.query(
|
||||
name, hash_key, range_comparison, range_values
|
||||
)
|
||||
|
||||
if items is None:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
|
||||
result = {
|
||||
"Count": len(items),
|
||||
"Items": [item.attrs for item in items],
|
||||
"ConsumedCapacityUnits": 1,
|
||||
}
|
||||
|
||||
# Implement this when we do pagination
|
||||
# if not last_page:
|
||||
# result["LastEvaluatedKey"] = {
|
||||
# "HashKeyElement": items[-1].hash_key,
|
||||
# "RangeKeyElement": items[-1].range_key,
|
||||
# }
|
||||
return dynamo_json_dump(result)
|
||||
|
||||
def scan(self):
|
||||
name = self.body["TableName"]
|
||||
|
||||
filters = {}
|
||||
scan_filters = self.body.get("ScanFilter", {})
|
||||
for attribute_name, scan_filter in scan_filters.items():
|
||||
# Keys are attribute names. Values are tuples of (comparison,
|
||||
# comparison_value)
|
||||
comparison_operator = scan_filter["ComparisonOperator"]
|
||||
comparison_values = scan_filter.get("AttributeValueList", [])
|
||||
filters[attribute_name] = (comparison_operator, comparison_values)
|
||||
|
||||
items, scanned_count, _ = dynamodb_backend.scan(name, filters)
|
||||
|
||||
if items is None:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
|
||||
result = {
|
||||
"Count": len(items),
|
||||
"Items": [item.attrs for item in items if item],
|
||||
"ConsumedCapacityUnits": 1,
|
||||
"ScannedCount": scanned_count,
|
||||
}
|
||||
|
||||
# Implement this when we do pagination
|
||||
# if not last_page:
|
||||
# result["LastEvaluatedKey"] = {
|
||||
# "HashKeyElement": items[-1].hash_key,
|
||||
# "RangeKeyElement": items[-1].range_key,
|
||||
# }
|
||||
return dynamo_json_dump(result)
|
||||
|
||||
def delete_item(self):
|
||||
name = self.body["TableName"]
|
||||
key = self.body["Key"]
|
||||
hash_key = key["HashKeyElement"]
|
||||
range_key = key.get("RangeKeyElement")
|
||||
return_values = self.body.get("ReturnValues", "")
|
||||
item = dynamodb_backend.delete_item(name, hash_key, range_key)
|
||||
if item:
|
||||
if return_values == "ALL_OLD":
|
||||
item_dict = item.to_json()
|
||||
else:
|
||||
item_dict = {"Attributes": []}
|
||||
item_dict["ConsumedCapacityUnits"] = 0.5
|
||||
return dynamo_json_dump(item_dict)
|
||||
else:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
||||
|
||||
def update_item(self):
|
||||
name = self.body["TableName"]
|
||||
key = self.body["Key"]
|
||||
hash_key = key["HashKeyElement"]
|
||||
range_key = key.get("RangeKeyElement")
|
||||
updates = self.body["AttributeUpdates"]
|
||||
|
||||
item = dynamodb_backend.update_item(name, hash_key, range_key, updates)
|
||||
|
||||
if item:
|
||||
item_dict = item.to_json()
|
||||
item_dict["ConsumedCapacityUnits"] = 0.5
|
||||
|
||||
return dynamo_json_dump(item_dict)
|
||||
else:
|
||||
er = "com.amazonaws.dynamodb.v20111205#ResourceNotFoundException"
|
||||
return self.error(er)
|
@ -4,7 +4,7 @@ import base64
|
||||
|
||||
from moto.core import BaseBackend, BaseModel
|
||||
from moto.core.utils import BackendDict
|
||||
from moto.dynamodb2.models import dynamodb_backends, DynamoJsonEncoder
|
||||
from moto.dynamodb.models import dynamodb_backends, DynamoJsonEncoder
|
||||
|
||||
|
||||
class ShardIterator(BaseModel):
|
||||
|
@ -130,9 +130,11 @@ class DomainDispatcherApplication(object):
|
||||
dynamo_api_version = (
|
||||
environ["HTTP_X_AMZ_TARGET"].split("_")[1].split(".")[0]
|
||||
)
|
||||
# If Newer API version, use dynamodb2
|
||||
if dynamo_api_version > "20111205":
|
||||
host = "dynamodb2"
|
||||
# Support for older API version
|
||||
if dynamo_api_version <= "20111205":
|
||||
host = "dynamodb_v20111205"
|
||||
else:
|
||||
host = "dynamodb"
|
||||
elif service == "sagemaker":
|
||||
host = "api.{service}.{region}.amazonaws.com".format(
|
||||
service=service, region=region
|
||||
|
@ -7,7 +7,7 @@ import boto3
|
||||
|
||||
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
alternative_service_names = {"lambda": "awslambda", "dynamodb": "dynamodb2"}
|
||||
alternative_service_names = {"lambda": "awslambda"}
|
||||
|
||||
|
||||
def get_moto_implementation(service_name):
|
||||
|
@ -1,5 +1,5 @@
|
||||
import pytest
|
||||
from moto.dynamodb2.models import Table
|
||||
from moto.dynamodb.models import Table
|
||||
|
||||
|
||||
@pytest.fixture
|
@ -6,7 +6,7 @@ import pytest
|
||||
|
||||
from moto import mock_dynamodb2
|
||||
from botocore.exceptions import ClientError
|
||||
from moto.dynamodb2.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
from moto.dynamodb.limits import HASH_KEY_MAX_LENGTH, RANGE_KEY_MAX_LENGTH
|
||||
|
||||
|
||||
@mock_dynamodb2
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@ import boto3
|
||||
import json
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_cloudformation, mock_dynamodb2
|
||||
from moto import mock_cloudformation, mock_dynamodb
|
||||
|
||||
|
||||
template_create_table = {
|
||||
@ -30,7 +30,7 @@ template_create_table = {
|
||||
}
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
@mock_cloudformation
|
||||
def test_delete_stack_dynamo_template_boto3():
|
||||
conn = boto3.client("cloudformation", region_name="us-east-1")
|
@ -4,10 +4,10 @@ import re
|
||||
import boto3
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression_with_dot_in_attr_name():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-2")
|
||||
table_name = "Test"
|
||||
@ -46,7 +46,7 @@ def test_condition_expression_with_dot_in_attr_name():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expressions():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -241,7 +241,7 @@ def _assert_conditional_check_failed_exception(exc):
|
||||
err["Message"].should.equal("The conditional request failed")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression_numerical_attribute():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
dynamodb.create_table(
|
||||
@ -284,7 +284,7 @@ def update_numerical_con_expr(key, con_expr, res, table):
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression__attr_doesnt_exist():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -322,7 +322,7 @@ def test_condition_expression__attr_doesnt_exist():
|
||||
_assert_conditional_check_failed_exception(exc)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression__or_order():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -345,7 +345,7 @@ def test_condition_expression__or_order():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression__and_order():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -370,7 +370,7 @@ def test_condition_expression__and_order():
|
||||
_assert_conditional_check_failed_exception(exc)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_condition_expression_with_reserved_keyword_as_attr_name():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-2")
|
||||
table_name = "Test"
|
@ -3,10 +3,10 @@ import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_error_on_wrong_value_for_consumed_capacity():
|
||||
resource = boto3.resource("dynamodb", region_name="ap-northeast-3")
|
||||
client = boto3.client("dynamodb", region_name="ap-northeast-3")
|
||||
@ -30,7 +30,7 @@ def test_error_on_wrong_value_for_consumed_capacity():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_consumed_capacity_get_unknown_item():
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
conn.create_table(
|
||||
@ -52,7 +52,7 @@ def test_consumed_capacity_get_unknown_item():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
@pytest.mark.parametrize(
|
||||
"capacity,should_have_capacity,should_have_table",
|
||||
[
|
@ -4,11 +4,11 @@ import sure # noqa # pylint: disable=unused-import
|
||||
from datetime import datetime
|
||||
import pytest
|
||||
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_standard():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -52,7 +52,7 @@ def test_create_table_standard():
|
||||
actual.should.have.key("ItemCount").equal(0)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_local_index():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -119,7 +119,7 @@ def test_create_table_with_local_index():
|
||||
actual.should.have.key("ItemCount").equal(0)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_gsi():
|
||||
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -196,7 +196,7 @@ def test_create_table_with_gsi():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_stream_specification():
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -223,7 +223,7 @@ def test_create_table_with_stream_specification():
|
||||
resp["TableDescription"].should.contain("StreamSpecification")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_tags():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -241,7 +241,7 @@ def test_create_table_with_tags():
|
||||
resp.should.have.key("Tags").equals([{"Key": "tk", "Value": "tv"}])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_pay_per_request():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -266,7 +266,7 @@ def test_create_table_pay_per_request():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table__provisioned_throughput():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -289,7 +289,7 @@ def test_create_table__provisioned_throughput():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_without_specifying_throughput():
|
||||
dynamodb_client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -310,7 +310,7 @@ def test_create_table_without_specifying_throughput():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_error_pay_per_request_with_provisioned_param():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -335,7 +335,7 @@ def test_create_table_error_pay_per_request_with_provisioned_param():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_ssespecification__false():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -356,7 +356,7 @@ def test_create_table_with_ssespecification__false():
|
||||
actual.shouldnt.have.key("SSEDescription")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_ssespecification__true():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -382,7 +382,7 @@ def test_create_table_with_ssespecification__true():
|
||||
) # Default KMS key for DynamoDB
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_with_ssespecification__custom_kms_key():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
@ -1,10 +1,10 @@
|
||||
import pytest
|
||||
|
||||
from moto.dynamodb2.exceptions import IncorrectOperandType, IncorrectDataType
|
||||
from moto.dynamodb2.models import Item, DynamoType
|
||||
from moto.dynamodb2.parsing.executors import UpdateExpressionExecutor
|
||||
from moto.dynamodb2.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb2.parsing.validators import UpdateExpressionValidator
|
||||
from moto.dynamodb.exceptions import IncorrectOperandType, IncorrectDataType
|
||||
from moto.dynamodb.models import Item, DynamoType
|
||||
from moto.dynamodb.parsing.executors import UpdateExpressionExecutor
|
||||
from moto.dynamodb.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb.parsing.validators import UpdateExpressionValidator
|
||||
|
||||
|
||||
def test_execution_of_if_not_exists_not_existing_value(table):
|
@ -1,8 +1,8 @@
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.exceptions import (
|
||||
InvalidTokenException,
|
||||
InvalidExpressionAttributeNameKey,
|
||||
)
|
||||
from moto.dynamodb2.parsing.tokens import ExpressionTokenizer, Token
|
||||
from moto.dynamodb.parsing.tokens import ExpressionTokenizer, Token
|
||||
|
||||
|
||||
def test_expression_tokenizer_single_set_action():
|
@ -1,6 +1,6 @@
|
||||
from moto.dynamodb2.exceptions import InvalidTokenException
|
||||
from moto.dynamodb2.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb2.parsing.reserved_keywords import ReservedKeywords
|
||||
from moto.dynamodb.exceptions import InvalidTokenException
|
||||
from moto.dynamodb.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb.parsing.reserved_keywords import ReservedKeywords
|
||||
|
||||
|
||||
def test_get_reserved_keywords():
|
@ -6,11 +6,11 @@ from botocore.exceptions import ClientError
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
from uuid import uuid4
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_get_item_without_range_key_boto3():
|
||||
client = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
table = client.create_table(
|
||||
@ -37,7 +37,7 @@ def test_get_item_without_range_key_boto3():
|
||||
ex.value.response["Error"]["Message"].should.equal("Validation Exception")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_query_filter_boto3():
|
||||
table_schema = {
|
||||
"KeySchema": [
|
||||
@ -80,7 +80,7 @@ def test_query_filter_boto3():
|
||||
res["Items"].should.equal([{"pk": "pk", "sk": "sk-1"}, {"pk": "pk", "sk": "sk-2"}])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_conditions():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -154,7 +154,7 @@ def test_boto3_conditions():
|
||||
results["Count"].should.equal(1)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_conditions_ignorecase():
|
||||
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -220,7 +220,7 @@ def test_boto3_conditions_ignorecase():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_put_item_with_conditions():
|
||||
import botocore
|
||||
|
||||
@ -294,7 +294,7 @@ def _create_table_with_range_key():
|
||||
return dynamodb.Table("users")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_range_key_set():
|
||||
table = _create_table_with_range_key()
|
||||
table.put_item(
|
||||
@ -331,7 +331,7 @@ def test_update_item_range_key_set():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_does_not_exist_is_created():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -363,7 +363,7 @@ def test_update_item_does_not_exist_is_created():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_add_value():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -386,7 +386,7 @@ def test_update_item_add_value():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_add_value_string_set():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -417,7 +417,7 @@ def test_update_item_add_value_string_set():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_delete_value_string_set():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -444,7 +444,7 @@ def test_update_item_delete_value_string_set():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_add_value_does_not_exist_is_created():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -463,7 +463,7 @@ def test_update_item_add_value_does_not_exist_is_created():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_with_expression():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -499,7 +499,7 @@ def assert_failure_due_to_key_not_in_schema(func, **kwargs):
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_add_with_expression():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -580,7 +580,7 @@ def test_update_item_add_with_expression():
|
||||
).should.have.raised(ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_add_with_nested_sets():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -617,7 +617,7 @@ def test_update_item_add_with_nested_sets():
|
||||
assert dict(table.get_item(Key=item_key)["Item"]) == current_item
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_delete_with_nested_sets():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -643,7 +643,7 @@ def test_update_item_delete_with_nested_sets():
|
||||
dict(table.get_item(Key=item_key)["Item"]).should.equal(current_item)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_delete_with_expression():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -699,7 +699,7 @@ def test_update_item_delete_with_expression():
|
||||
).should.have.raised(ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_query_gsi_range_comparison():
|
||||
table = _create_table_with_range_key()
|
||||
|
||||
@ -795,7 +795,7 @@ def test_boto3_query_gsi_range_comparison():
|
||||
item["created"].should.equal(expected[index])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_table_throughput():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -827,7 +827,7 @@ def test_boto3_update_table_throughput():
|
||||
table.provisioned_throughput["WriteCapacityUnits"].should.equal(11)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_table_gsi_throughput():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -894,7 +894,7 @@ def test_boto3_update_table_gsi_throughput():
|
||||
gsi_throughput["WriteCapacityUnits"].should.equal(11)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_table_gsi_create():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -976,7 +976,7 @@ def test_update_table_gsi_create():
|
||||
table.global_secondary_indexes.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_table_gsi_throughput():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -1018,7 +1018,7 @@ def test_update_table_gsi_throughput():
|
||||
table.global_secondary_indexes.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_query_pagination():
|
||||
table = _create_table_with_range_key()
|
||||
for i in range(10):
|
||||
@ -1050,7 +1050,7 @@ def test_query_pagination():
|
||||
subjects.should.equal(set(range(10)))
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_scan_by_index():
|
||||
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -1152,7 +1152,7 @@ def test_scan_by_index():
|
||||
assert last_eval_key["lsi_range_key"]["S"] == "1"
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
@pytest.mark.parametrize("create_item_first", [False, True])
|
||||
@pytest.mark.parametrize(
|
||||
"expression", ["set h=:New", "set r=:New", "set x=:New, r=:New"]
|
@ -4,12 +4,12 @@ import sure # noqa # pylint: disable=unused-import
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
from moto.core import ACCOUNT_ID
|
||||
import botocore
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_create_table_boto3():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -72,7 +72,7 @@ def test_create_table_boto3():
|
||||
actual.should.have.key("ItemCount").equal(0)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_delete_table_boto3():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
conn.create_table(
|
||||
@ -94,7 +94,7 @@ def test_delete_table_boto3():
|
||||
ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_item_add_and_describe_and_update_boto3():
|
||||
conn = boto3.resource("dynamodb", region_name="us-west-2")
|
||||
table = conn.create_table(
|
||||
@ -130,7 +130,7 @@ def test_item_add_and_describe_and_update_boto3():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_item_put_without_table_boto3():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
|
||||
@ -149,7 +149,7 @@ def test_item_put_without_table_boto3():
|
||||
ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_get_item_with_undeclared_table_boto3():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
|
||||
@ -161,7 +161,7 @@ def test_get_item_with_undeclared_table_boto3():
|
||||
ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_delete_item_boto3():
|
||||
conn = boto3.resource("dynamodb", region_name="us-west-2")
|
||||
table = conn.create_table(
|
||||
@ -188,7 +188,7 @@ def test_delete_item_boto3():
|
||||
table.delete_item(Key={"id": "LOLCat Forum"})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_delete_item_with_undeclared_table_boto3():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
|
||||
@ -204,7 +204,7 @@ def test_delete_item_with_undeclared_table_boto3():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_scan_with_undeclared_table_boto3():
|
||||
conn = boto3.client("dynamodb", region_name="us-west-2")
|
||||
|
||||
@ -216,7 +216,7 @@ def test_scan_with_undeclared_table_boto3():
|
||||
ex.value.response["Error"]["Message"].should.equal("Requested resource not found")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_get_key_schema():
|
||||
conn = boto3.resource("dynamodb", region_name="us-west-2")
|
||||
table = conn.create_table(
|
||||
@ -229,7 +229,7 @@ def test_get_key_schema():
|
||||
table.key_schema.should.equal([{"AttributeName": "id", "KeyType": "HASH"}])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_double_nested_remove():
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
conn.create_table(
|
||||
@ -264,7 +264,7 @@ def test_update_item_double_nested_remove():
|
||||
dict(returned_item["Item"]).should.equal(expected_item)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_item_set_boto3():
|
||||
conn = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
table = conn.create_table(
|
||||
@ -288,7 +288,7 @@ def test_update_item_set_boto3():
|
||||
dict(returned_item).should.equal({"username": "steve", "foo": "bar", "blah": "baz"})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_create_table():
|
||||
dynamodb = boto3.resource("dynamodb", region_name="us-east-1")
|
||||
|
||||
@ -313,7 +313,7 @@ def _create_user_table():
|
||||
return dynamodb.Table("users")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_conditions():
|
||||
table = _create_user_table()
|
||||
|
||||
@ -326,7 +326,7 @@ def test_boto3_conditions():
|
||||
response["Items"][0].should.equal({"username": "johndoe"})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_put_item_conditions_pass():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -338,7 +338,7 @@ def test_boto3_put_item_conditions_pass():
|
||||
assert dict(final_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_put_item_conditions_pass_because_expect_not_exists_by_compare_to_null():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -350,7 +350,7 @@ def test_boto3_put_item_conditions_pass_because_expect_not_exists_by_compare_to_
|
||||
assert dict(final_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_put_item_conditions_pass_because_expect_exists_by_compare_to_not_null():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -362,7 +362,7 @@ def test_boto3_put_item_conditions_pass_because_expect_exists_by_compare_to_not_
|
||||
assert dict(final_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_put_item_conditions_fail():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -372,7 +372,7 @@ def test_boto3_put_item_conditions_fail():
|
||||
).should.throw(botocore.client.ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_fail():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "baz"})
|
||||
@ -384,7 +384,7 @@ def test_boto3_update_item_conditions_fail():
|
||||
).should.throw(botocore.client.ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_fail_because_expect_not_exists():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "baz"})
|
||||
@ -396,7 +396,7 @@ def test_boto3_update_item_conditions_fail_because_expect_not_exists():
|
||||
).should.throw(botocore.client.ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_fail_because_expect_not_exists_by_compare_to_null():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "baz"})
|
||||
@ -408,7 +408,7 @@ def test_boto3_update_item_conditions_fail_because_expect_not_exists_by_compare_
|
||||
).should.throw(botocore.client.ClientError)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_pass():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -422,7 +422,7 @@ def test_boto3_update_item_conditions_pass():
|
||||
assert dict(returned_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_pass_because_expect_not_exists():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -436,7 +436,7 @@ def test_boto3_update_item_conditions_pass_because_expect_not_exists():
|
||||
assert dict(returned_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_pass_because_expect_not_exists_by_compare_to_null():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -450,7 +450,7 @@ def test_boto3_update_item_conditions_pass_because_expect_not_exists_by_compare_
|
||||
assert dict(returned_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_item_conditions_pass_because_expect_exists_by_compare_to_not_null():
|
||||
table = _create_user_table()
|
||||
table.put_item(Item={"username": "johndoe", "foo": "bar"})
|
||||
@ -464,7 +464,7 @@ def test_boto3_update_item_conditions_pass_because_expect_exists_by_compare_to_n
|
||||
assert dict(returned_item)["Item"]["foo"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_boto3_update_settype_item_with_conditions():
|
||||
class OrderedSet(set):
|
||||
"""A set with predictable iteration order"""
|
||||
@ -501,7 +501,7 @@ def test_boto3_update_settype_item_with_conditions():
|
||||
assert dict(returned_item)["Item"]["foo"].should.equal(set(["baz"]))
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_scan_pagination():
|
||||
table = _create_user_table()
|
||||
|
||||
@ -524,7 +524,7 @@ def test_scan_pagination():
|
||||
usernames.should.equal(set(expected_usernames))
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_scan_by_index():
|
||||
dynamodb = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
@ -1,10 +1,10 @@
|
||||
import boto3
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from moto import mock_dynamodb2
|
||||
from moto import mock_dynamodb
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_table__billing_mode():
|
||||
client = boto3.client("dynamodb", region_name="us-east-1")
|
||||
client.create_table(
|
||||
@ -33,7 +33,7 @@ def test_update_table__billing_mode():
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_table_throughput():
|
||||
conn = boto3.resource("dynamodb", region_name="us-west-2")
|
||||
table = conn.create_table(
|
||||
@ -53,7 +53,7 @@ def test_update_table_throughput():
|
||||
table.provisioned_throughput["WriteCapacityUnits"].should.equal(6)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
@mock_dynamodb
|
||||
def test_update_table__enable_stream():
|
||||
conn = boto3.client("dynamodb", region_name="us-east-1")
|
||||
|
@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from moto.dynamodb2.exceptions import (
|
||||
from moto.dynamodb.exceptions import (
|
||||
AttributeIsReservedKeyword,
|
||||
ExpressionAttributeValueNotDefined,
|
||||
AttributeDoesNotExist,
|
||||
@ -8,14 +8,14 @@ from moto.dynamodb2.exceptions import (
|
||||
IncorrectOperandType,
|
||||
InvalidUpdateExpressionInvalidDocumentPath,
|
||||
)
|
||||
from moto.dynamodb2.models import Item, DynamoType
|
||||
from moto.dynamodb2.parsing.ast_nodes import (
|
||||
from moto.dynamodb.models import Item, DynamoType
|
||||
from moto.dynamodb.parsing.ast_nodes import (
|
||||
NodeDepthLeftTypeFetcher,
|
||||
UpdateExpressionSetAction,
|
||||
DDBTypedValue,
|
||||
)
|
||||
from moto.dynamodb2.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb2.parsing.validators import UpdateExpressionValidator
|
||||
from moto.dynamodb.parsing.expressions import UpdateExpressionParser
|
||||
from moto.dynamodb.parsing.validators import UpdateExpressionValidator
|
||||
|
||||
|
||||
def test_valid_update_expression(table):
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
# This file is intentionally left blank.
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
import moto.server as server
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
"""
|
||||
|
||||
|
||||
def test_table_list():
|
||||
backend = server.create_backend_app("dynamodb2")
|
||||
test_client = backend.test_client()
|
||||
res = test_client.get("/")
|
||||
res.status_code.should.equal(404)
|
||||
|
||||
headers = {"X-Amz-Target": "TestTable.ListTables"}
|
||||
res = test_client.get("/", headers=headers)
|
||||
res.data.should.contain(b"TableNames")
|
||||
res.headers.should.have.key("X-Amz-Crc32")
|
1
tests/test_dynamodb_v20111205/__init__.py
Normal file
1
tests/test_dynamodb_v20111205/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# This file is intentionally left blank.
|
1336
tests/test_dynamodb_v20111205/test_server.py
Normal file
1336
tests/test_dynamodb_v20111205/test_server.py
Normal file
File diff suppressed because it is too large
Load Diff
70
tests/test_dynamodb_v20111205/test_servermode.py
Normal file
70
tests/test_dynamodb_v20111205/test_servermode.py
Normal file
@ -0,0 +1,70 @@
|
||||
import json
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
import requests
|
||||
|
||||
from moto import settings
|
||||
from unittest import SkipTest
|
||||
from uuid import uuid4
|
||||
|
||||
"""
|
||||
Test the different server responses
|
||||
Docs:
|
||||
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Appendix.APIv20111205.html
|
||||
"""
|
||||
|
||||
|
||||
def test_table_list():
|
||||
if not settings.TEST_SERVER_MODE:
|
||||
raise SkipTest("Only run test with external server")
|
||||
headers = {
|
||||
"X-Amz-Target": "DynamoDB_20111205.ListTables",
|
||||
"Host": "dynamodb.us-east-1.amazonaws.com",
|
||||
}
|
||||
requests.post(settings.test_server_mode_endpoint() + "/moto-api/reset")
|
||||
res = requests.get(settings.test_server_mode_endpoint(), headers=headers)
|
||||
res.status_code.should.equal(200)
|
||||
json.loads(res.content).should.equal({"TableNames": []})
|
||||
|
||||
|
||||
def test_create_table():
|
||||
if not settings.TEST_SERVER_MODE:
|
||||
raise SkipTest("Only run test with external server")
|
||||
|
||||
table_name = str(uuid4())
|
||||
|
||||
headers = {
|
||||
"X-Amz-Target": "DynamoDB_20111205.CreateTable",
|
||||
"Content-Type": "application/x-amz-json-1.0",
|
||||
"AUTHORIZATION": "AWS4-HMAC-SHA256 Credential=ACCESS_KEY/20220226/us-east-1/dynamodb/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=sig",
|
||||
}
|
||||
request_body = {
|
||||
"TableName": table_name,
|
||||
"KeySchema": {
|
||||
"HashKeyElement": {"AttributeName": "hkey", "AttributeType": "S"}
|
||||
},
|
||||
"ProvisionedThroughput": {"ReadCapacityUnits": 5, "WriteCapacityUnits": 10},
|
||||
}
|
||||
res = requests.post(
|
||||
settings.test_server_mode_endpoint(), headers=headers, json=request_body
|
||||
)
|
||||
|
||||
res = json.loads(res.content)["Table"]
|
||||
res.should.have.key("CreationDateTime")
|
||||
del res["CreationDateTime"]
|
||||
res.should.equal(
|
||||
{
|
||||
"KeySchema": {
|
||||
"HashKeyElement": {"AttributeName": "hkey", "AttributeType": "S"}
|
||||
},
|
||||
"ProvisionedThroughput": {"ReadCapacityUnits": 5, "WriteCapacityUnits": 10},
|
||||
"TableName": table_name,
|
||||
"TableStatus": "ACTIVE",
|
||||
"ItemCount": 0,
|
||||
"TableSizeBytes": 0,
|
||||
}
|
||||
)
|
||||
|
||||
headers["X-Amz-Target"] = "DynamoDB_20111205.ListTables"
|
||||
res = requests.get(settings.test_server_mode_endpoint(), headers=headers)
|
||||
res = json.loads(res.content)
|
||||
table_name.should.be.within(res["TableNames"])
|
@ -3,7 +3,7 @@ from __future__ import print_function
|
||||
import pytest
|
||||
|
||||
import boto3
|
||||
from moto import mock_dynamodb2, mock_dynamodbstreams
|
||||
from moto import mock_dynamodb, mock_dynamodbstreams
|
||||
|
||||
|
||||
class TestCore:
|
||||
@ -11,7 +11,7 @@ class TestCore:
|
||||
mocks = []
|
||||
|
||||
def setup(self):
|
||||
self.mocks = [mock_dynamodb2(), mock_dynamodbstreams()]
|
||||
self.mocks = [mock_dynamodb(), mock_dynamodbstreams()]
|
||||
for m in self.mocks:
|
||||
m.start()
|
||||
|
||||
@ -197,7 +197,7 @@ class TestEdges:
|
||||
mocks = []
|
||||
|
||||
def setup(self):
|
||||
self.mocks = [mock_dynamodb2(), mock_dynamodbstreams()]
|
||||
self.mocks = [mock_dynamodb(), mock_dynamodbstreams()]
|
||||
for m in self.mocks:
|
||||
m.start()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user