コード例 #1
0
def test_execution_of_delete_element_from_a_string_attribute():
    """A delete statement must use a value of type SS in order to delete elements from a set."""
    update_expression = "delete s :value"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "S": "5"
            },
        },
    )
    try:
        validated_ast = UpdateExpressionValidator(
            update_expression_ast,
            expression_attribute_names=None,
            expression_attribute_values={
                ":value": {
                    "SS": ["value2"]
                }
            },
            item=item,
        ).validate()
        UpdateExpressionExecutor(validated_ast, item, None).execute()
        assert False, "Must raise exception"
    except IncorrectDataType:
        assert True
コード例 #2
0
def test_execution_of_if_not_exists_with_non_existing_attribute_should_return_value(
    table, ):
    update_expression = "SET a = if_not_exists(b, :val)"
    update_expression_values = {":val": {"N": "4"}}
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        range_key=None,
        attrs={"id": {
            "S": "1"
        }},
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values=update_expression_values,
        item=item,
        table=table,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        range_key=None,
        attrs={
            "id": {
                "S": "1"
            },
            "a": {
                "N": "4"
            }
        },
    )
    assert expected_item == item
コード例 #3
0
def test_execution_of__delete_element_from_set_invalid_value(
        expression_attribute_values, unexpected_data_type):
    """A delete statement must use a value of type SS in order to delete elements from a set."""
    update_expression = "delete s :value"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "SS": ["value1", "value2", "value3"]
            },
        },
    )
    try:
        validated_ast = UpdateExpressionValidator(
            update_expression_ast,
            expression_attribute_names=None,
            expression_attribute_values=expression_attribute_values,
            item=item,
        ).validate()
        UpdateExpressionExecutor(validated_ast, item, None).execute()
        assert False, "Must raise exception"
    except IncorrectOperandType as e:
        assert e.operator_or_function == "operator: DELETE"
        assert e.operand_type == unexpected_data_type
コード例 #4
0
def test_execution_of_add_set_to_a_number(table):
    update_expression = "add s :value"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "N": "5"
            },
        },
    )
    try:
        validated_ast = UpdateExpressionValidator(
            update_expression_ast,
            expression_attribute_names=None,
            expression_attribute_values={
                ":value": {
                    "SS": ["s1"]
                }
            },
            item=item,
            table=table,
        ).validate()
        UpdateExpressionExecutor(validated_ast, item, None).execute()
        expected_item = Item(
            hash_key=DynamoType({"S": "id"}),
            hash_key_type="TYPE",
            range_key=None,
            range_key_type=None,
            attrs={
                "id": {
                    "S": "foo2"
                },
                "s": {
                    "N": "15"
                }
            },
        )
        assert expected_item == item
        assert False
    except IncorrectDataType:
        assert True
コード例 #5
0
def test_execution_of_if_not_exists_with_existing_attribute_should_return_attribute(
):
    update_expression = "SET a = if_not_exists(b, a)"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "1"
            },
            "a": {
                "S": "A"
            },
            "b": {
                "S": "B"
            }
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values=None,
        item=item,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "1"
            },
            "a": {
                "S": "B"
            },
            "b": {
                "S": "B"
            }
        },
    )
    assert expected_item == item
コード例 #6
0
def test_execution_of_sum_operation(table):
    update_expression = "SET a = a + b"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "1"
            },
            "a": {
                "N": "3"
            },
            "b": {
                "N": "4"
            }
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values=None,
        item=item,
        table=table,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "1"
            },
            "a": {
                "N": "7"
            },
            "b": {
                "N": "4"
            }
        },
    )
    assert expected_item == item
コード例 #7
0
def test_execution_of_add_to_a_set(table):
    update_expression = "ADD s :value"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "SS": ["value1", "value2", "value3"]
            },
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values={
            ":value": {
                "SS": ["value2", "value5"]
            }
        },
        item=item,
        table=table,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "SS": ["value1", "value2", "value3", "value5"]
            },
        },
    )
    assert expected_item == item
コード例 #8
0
def test_execution_of_add_number():
    update_expression = "add s :value"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "N": "5"
            },
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values={
            ":value": {
                "N": "10"
            }
        },
        item=item,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "N": "15"
            }
        },
    )
    assert expected_item == item
コード例 #9
0
ファイル: __init__.py プロジェクト: limitusus/moto
    def update_item(
        self,
        table_name,
        key,
        update_expression,
        expression_attribute_names,
        expression_attribute_values,
        attribute_updates=None,
        expected=None,
        condition_expression=None,
    ):
        table = self.get_table(table_name)

        # Support spaces between operators in an update expression
        # E.g. `a = b + c` -> `a=b+c`
        if update_expression:
            # Parse expression to get validation errors
            update_expression_ast = UpdateExpressionParser.make(
                update_expression)
            update_expression = re.sub(r"\s*([=\+-])\s*", "\\1",
                                       update_expression)

        if all([table.hash_key_attr in key, table.range_key_attr in key]):
            # Covers cases where table has hash and range keys, ``key`` param
            # will be a dict
            hash_value = DynamoType(key[table.hash_key_attr])
            range_value = DynamoType(key[table.range_key_attr])
        elif table.hash_key_attr in key:
            # Covers tables that have a range key where ``key`` param is a dict
            hash_value = DynamoType(key[table.hash_key_attr])
            range_value = None
        else:
            # Covers other cases
            hash_value = DynamoType(key)
            range_value = None

        item = table.get_item(hash_value, range_value)
        orig_item = copy.deepcopy(item)

        if not expected:
            expected = {}

        if not get_expected(expected).expr(item):
            raise ConditionalCheckFailed
        condition_op = get_filter_expression(
            condition_expression,
            expression_attribute_names,
            expression_attribute_values,
        )
        if not condition_op.expr(item):
            raise ConditionalCheckFailed

        # Update does not fail on new items, so create one
        if item is None:
            data = {table.hash_key_attr: {hash_value.type: hash_value.value}}
            if range_value:
                data.update({
                    table.range_key_attr: {
                        range_value.type: range_value.value
                    }
                })

            table.put_item(data)
            item = table.get_item(hash_value, range_value)

        if update_expression:
            validated_ast = UpdateExpressionValidator(
                update_expression_ast,
                expression_attribute_names=expression_attribute_names,
                expression_attribute_values=expression_attribute_values,
                item=item,
            ).validate()
            try:
                UpdateExpressionExecutor(validated_ast, item,
                                         expression_attribute_names).execute()
            except ItemSizeTooLarge:
                raise ItemSizeToUpdateTooLarge()
        else:
            item.update_with_attribute_updates(attribute_updates)
        if table.stream_shard is not None:
            table.stream_shard.add(orig_item, item)
        return item
コード例 #10
0
def test_execution_of_remove_in_list():
    update_expression = "Remove itemmap.itemlist[1]"
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "itemmap": {
                "M": {
                    "itemlist": {
                        "L": [
                            {
                                "M": {
                                    "foo00": {
                                        "S": "bar1"
                                    },
                                    "foo01": {
                                        "S": "bar2"
                                    }
                                }
                            },
                            {
                                "M": {
                                    "foo10": {
                                        "S": "bar1"
                                    },
                                    "foo11": {
                                        "S": "bar2"
                                    }
                                }
                            },
                        ]
                    }
                }
            },
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=None,
        expression_attribute_values=None,
        item=item,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item, None).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        hash_key_type="TYPE",
        range_key=None,
        range_key_type=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "itemmap": {
                "M": {
                    "itemlist": {
                        "L": [
                            {
                                "M": {
                                    "foo00": {
                                        "S": "bar1"
                                    },
                                    "foo01": {
                                        "S": "bar2"
                                    }
                                }
                            },
                        ]
                    }
                }
            },
        },
    )
    assert expected_item == item
コード例 #11
0
def test_execution_of_delete_element_from_set(table, attr_name):
    expression_attribute_names = {"#placeholder": "s"}
    update_expression = "delete {} :value".format(attr_name)
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    item = Item(
        hash_key=DynamoType({"S": "id"}),
        range_key=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "SS": ["value1", "value2", "value3"]
            }
        },
    )
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=expression_attribute_names,
        expression_attribute_values={
            ":value": {
                "SS": ["value2", "value5"]
            }
        },
        item=item,
        table=table,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item,
                             expression_attribute_names).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        range_key=None,
        attrs={
            "id": {
                "S": "foo2"
            },
            "s": {
                "SS": ["value1", "value3"]
            },
        },
    )
    assert expected_item == item

    # delete last elements
    update_expression = "delete {} :value".format(attr_name)
    update_expression_ast = UpdateExpressionParser.make(update_expression)
    validated_ast = UpdateExpressionValidator(
        update_expression_ast,
        expression_attribute_names=expression_attribute_names,
        expression_attribute_values={
            ":value": {
                "SS": ["value1", "value3"]
            }
        },
        item=item,
        table=table,
    ).validate()
    UpdateExpressionExecutor(validated_ast, item,
                             expression_attribute_names).execute()
    expected_item = Item(
        hash_key=DynamoType({"S": "id"}),
        range_key=None,
        attrs={"id": {
            "S": "foo2"
        }},
    )
    assert expected_item == item