Exemplo n.º 1
0
def test_dynamodb():

    dynamodb_dict = dict_to_dynamodb(sample_input)

    assert dynamodb_dict["sample1"] == "Test Data"
    assert math.isclose(float(dynamodb_dict["sample2"]), decimal.Decimal(2.0))
    assert dynamodb_dict["sample3"] is True
    assert dynamodb_dict["sample5"] is None
    assert dynamodb_dict["sample6"] == {"test": True}
    assert dynamodb_dict["sample7"] == ["Hello", "World"]
    assert dynamodb_dict["sample8"] == [
        decimal.Decimal(9), decimal.Decimal(10)
    ]
    assert dynamodb_dict["DecimalInt"] == decimal.Decimal(42)
    assert dynamodb_dict["DecimalFloat"] == decimal.Decimal(
        2.0) / decimal.Decimal(3.0)
    assert dynamodb_dict["a_tuple"] == [1, 2, 3]
    assert dynamodb_dict[
        "42"] == "my_key_is_an_int"  # test conversion of an int key to a string
    assert dynamodb_dict["test_date_time"] == "2019-06-04T20:18:55+00:00"
    assert dynamodb_dict["zero_len_string"] is None

    # while dictim is case insensitive, when we convert to dict for DynamoDB it becomes case sensitive
    assert list(dynamodb_dict["dictim"]["HI"])[0] == "there"
    assert dynamodb_dict["dictim"]["HI"]["there"] == 1  # actually Decimal(1)
    assert dynamodb_dict["dictim"].get(
        "hi") is None  # we're back to case sensitivity

    dynamodb_access = DynamoDBAccess(
        profile_name=test_awsimple_str,
        table_name=test_awsimple_str,
        cache_dir=Path("cache"),
        cache_life=timedelta(seconds=1).total_seconds())
    dynamodb_access.create_table(id_str)
    dynamodb_access.put_item(dynamodb_dict)

    sample_from_db = dynamodb_access.get_item(id_str, dict_id)
    assert sample_from_db == dynamodb_dict  # make sure we get back exactly what we wrote

    table_contents = dynamodb_access.scan_table_cached()
    assert not dynamodb_access.cache_hit
    check_table_contents(table_contents)

    table_contents = dynamodb_access.scan_table()
    check_table_contents(table_contents)

    table_contents = dynamodb_access.scan_table_cached()
    assert dynamodb_access.cache_hit
    check_table_contents(table_contents)

    assert dynamodb_access.get_primary_keys() == (id_str, None)  # no sort key
Exemplo n.º 2
0
    def run(self):
        preferences = get_preferences(self.ui_type)
        backup_directory = preferences.backup_directory
        dry_run = preferences.dry_run
        exclusions = ExclusionPreferences(
            self.backup_type.name).get_no_comments()

        tables = DynamoDBAccess(
            profile_name=preferences.aws_profile).get_table_names()
        self.info_out(f"found {len(tables)} DynamoDB tables")
        count = 0
        for table_name in tables:

            # awsimple will update immediately if number of table rows changes, but backup from scratch every so often to be safe
            cache_life = timedelta(days=1).total_seconds()

            if table_name in exclusions:
                self.info_out(f"excluding {table_name}")
            elif dry_run:
                self.info_out(f"dry run {table_name}")
            else:
                self.info_out(f"{table_name}")
                table = DynamoDBAccess(table_name, cache_life=cache_life)
                table_contents = table.scan_table_cached()

                dir_path = Path(backup_directory, "dynamodb")
                dir_path.mkdir(parents=True, exist_ok=True)
                with Path(dir_path, f"{table_name}.pickle").open("wb") as f:
                    pickle.dump(table_contents, f)
                with Path(dir_path, f"{table_name}.json").open("w") as f:
                    f.write(dynamodb_to_json(table_contents, indent=4))
                count += 1

        self.info_out(
            f"{count} tables, {count} backed up, {len(exclusions)} excluded")
def test_dynamodb_create_table():
    table_name = f"{test_awsimple_str}temp"

    dynamodb_access = DynamoDBAccess(table_name,
                                     profile_name=test_awsimple_str)

    dynamodb_access.create_table("id")
    assert dynamodb_access.table_exists(
    )  # create_table has a waiter so the table should exist at this point

    dynamodb_access.put_item({"id": "me", "value": 1})

    table_data = dynamodb_access.scan_table_cached()
    pprint(table_data)
    assert table_data[0]["id"] == "me"
    assert table_data[0]["value"] == 1
    assert len(table_data) == 1
    assert len(dynamodb_access.scan_table_cached(invalidate_cache=True)) == 1

    dynamodb_access.delete_table()
    assert not dynamodb_access.delete_table(
    )  # delete_table has a waiter so the table should exist at this point
Exemplo n.º 4
0
def musical_instruments_example():

    """
    This example shows how to use DynamoDB to keep a table of musical instruments.

    """

    dynamodb_access = DynamoDBAccess("musical_instruments_example", profile_name="testawsimple", cache_life=60)  # short cache life for development

    # Our primary key is a composite of partition (manufacturer) and sort (serial_number).
    # For a particular manufacturer, serial numbers define exactly one instrument (for this example we are assuming a serial number can be represented as an
    # integer and doesn't have to be a string).
    dynamodb_access.create_table("manufacturer", "serial_number", sort_key_type=int)

    # we have to convert float to a Decimal for DynamoDB
    dynamodb_access.put_item(dict_to_dynamodb({"manufacturer": "Gibson", "serial_number": 1234, "model": "Ripper", "year": 1983, "price": 1299.50}))
    dynamodb_access.put_item(dict_to_dynamodb({"manufacturer": "Gibson", "serial_number": 5678, "model": "Thunderbird", "year": 1977, "price": 2399.50}))
    dynamodb_access.put_item(
        dict_to_dynamodb(
            {
                "manufacturer": "Fender",
                "serial_number": 1234,
                "model": "Precision",
                "year": 2008,
                "price": 1800.0,
            }  # same serial number as the Gibson Ripper, but that's OK since this is Fender
        )
    )

    # get all the Gibson instruments
    start = time.time()
    item = dynamodb_access.query("manufacturer", "Gibson")  # this can (and will in this case) be multiple items
    end = time.time()
    pprint(item)
    print(f"query took {end-start} seconds")  # nominal 0.1 to 0.15 seconds
    print()

    # get the entire inventory
    start = time.time()
    all_items = dynamodb_access.scan_table_cached()  # use cached if the table is large and *only* if we know our table is slowly or never changing
    end = time.time()
    pprint(all_items)
    print(f"scan took {end-start} seconds ({dynamodb_access.cache_hit=})")  # always fast for this small data set, but caching can offer a speedup for large tables