Created
March 24, 2022 22:37
-
-
Save therightstuff/7e9103d3aaa78d2ca176e72eb12e5b1a to your computer and use it in GitHub Desktop.
Storing and Retrieving Unstructured DynamoDB objects in C# with the AWS SDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// The object mapping used to store structured test data | |
/// </summary> | |
private class StructuredDynamoDbTestObject | |
{ | |
/// <summary> | |
/// The data key. | |
/// </summary> | |
[DynamoDBHashKey("structured_key")] | |
public string StructuredKey { get; set; } | |
} | |
/// <summary> | |
/// Test that uploaded structured data can be downloaded | |
/// Designed for testing against localstack, see https://github.com/localstack/localstack | |
/// </summary> | |
[TestMethod] | |
public void StructuredDataUploadAndDownload() | |
{ | |
// assumes table has been created | |
const string tableName = "structured-data-upload-download-test"; | |
// the partition key name | |
const string keyName = "structured_key"; | |
// assumes AwsDynamoDbClient has been configured and is pointing to localstack | |
var dynamoDbContext = new DynamoDBContext( | |
AwsDynamoDbClient, | |
new DynamoDBContextConfig | |
{ | |
ConsistentRead = true | |
}); | |
var dynamoDbOperationConfig = new DynamoDBOperationConfig | |
{ | |
OverrideTableName = tableName, BackwardQuery = false | |
}; | |
var expectedTicks = $"{DateTime.UtcNow.Ticks}"; | |
var testObject = new StructuredDynamoDbTestObject | |
{ | |
StructuredKey = expectedTicks | |
}; | |
dynamoDbContext | |
.SaveAsync(testObject, dynamoDbOperationConfig) | |
.Wait(); | |
var ticks = dynamoDbContext | |
.LoadAsync(testObject, dynamoDbOperationConfig) | |
.Result; | |
Assert.AreEqual(expectedTicks, ticks.StructuredKey); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Test that unstructured data can be uploaded and downloaded | |
/// Designed for testing against localstack, see https://github.com/localstack/localstack | |
/// </summary> | |
[TestMethod] | |
public void UnstructuredDataUploadAndDownload() | |
{ | |
// assumes table has been created | |
const string tableName = "unstructured-data-upload-download-test"; | |
// the partition key name | |
const string keyName = "unstructured_key"; | |
const string testKeyValue = "test_key_value"; | |
const string stringValueKey = "stringValue"; | |
const string stringListKey = "stringList"; | |
const string stringSetKey = "stringSet"; | |
const string numberMapKey = "numberMap"; | |
const string multilevelMapKey = "multilevelMap"; | |
const string innerKey = "innerKey"; | |
const string initialStringValue = "initial value"; | |
const string updatedStringValue = "updated value"; | |
const string oneString = "one"; | |
const string twoString = "two"; | |
const string threeString = "three"; | |
const string oneNumeric = "1"; | |
const string twoNumeric = "2"; | |
var putItemRequest = new PutItemRequest | |
{ | |
TableName = tableName, | |
Item = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
keyName, new AttributeValue(testKeyValue) | |
}, | |
{ | |
stringValueKey, new AttributeValue | |
{ | |
S = initialStringValue | |
} | |
}, | |
{ | |
stringListKey, new AttributeValue | |
{ | |
L = new List<AttributeValue> | |
{ | |
new AttributeValue | |
{ | |
S = oneString | |
}, | |
new AttributeValue | |
{ | |
S = twoString | |
} | |
} | |
} | |
}, | |
{ | |
stringSetKey, new AttributeValue | |
{ | |
SS = new List<string> | |
{ | |
oneString, twoString | |
} | |
} | |
}, | |
{ | |
numberMapKey, new AttributeValue | |
{ | |
M = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
oneString, new AttributeValue | |
{ | |
N = oneNumeric | |
} | |
}, | |
{ | |
twoString, new AttributeValue | |
{ | |
N = twoNumeric | |
} | |
} | |
} | |
} | |
}, | |
{ | |
multilevelMapKey, new AttributeValue | |
{ | |
M = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
oneString, new AttributeValue | |
{ | |
N = oneNumeric | |
} | |
}, | |
{ | |
twoString, new AttributeValue | |
{ | |
M = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
innerKey, new AttributeValue | |
{ | |
BOOL = true | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
}; | |
// assumes AwsDynamoDbClient has been configured and is pointing to localstack | |
AwsDynamoDbClient | |
.PutItemAsync(putItemRequest) | |
.Wait(); | |
var initialUploadedItem = AwsDynamoDbClient | |
.GetItemAsync( | |
new GetItemRequest | |
{ | |
TableName = tableName, | |
Key = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
keyName, new AttributeValue | |
{ | |
S = testKeyValue | |
} | |
} | |
} | |
}) | |
.Result | |
.Item; | |
Assert.AreEqual(testKeyValue, initialUploadedItem[keyName].S); | |
Assert.AreEqual(initialStringValue, initialUploadedItem[stringValueKey].S); | |
Assert.AreEqual(2, initialUploadedItem[stringListKey].L.Count); | |
Assert.AreEqual(oneString, initialUploadedItem[stringListKey].L[0].S); | |
Assert.AreEqual(twoString, initialUploadedItem[stringListKey].L[1].S); | |
Assert.AreEqual(2, initialUploadedItem[stringSetKey].SS.Count); | |
Assert.IsTrue(initialUploadedItem[stringSetKey].SS.IndexOf(twoString) > -1); | |
Assert.IsTrue(initialUploadedItem[stringSetKey].SS.IndexOf(threeString) == -1); | |
Assert.AreEqual(oneNumeric, initialUploadedItem[numberMapKey].M[oneString].N); | |
Assert.AreEqual(true, initialUploadedItem[multilevelMapKey].M[twoString].M[innerKey].BOOL); | |
// modify simple and complex values and re-upload | |
initialUploadedItem[stringValueKey] = new AttributeValue | |
{ | |
S = updatedStringValue | |
}; | |
initialUploadedItem[stringListKey] = new AttributeValue | |
{ | |
L = new List<AttributeValue> | |
{ | |
new AttributeValue | |
{ | |
S = oneString | |
}, | |
new AttributeValue | |
{ | |
S = twoString | |
}, | |
new AttributeValue | |
{ | |
S = threeString | |
} | |
} | |
}; | |
initialUploadedItem[stringSetKey] = new AttributeValue | |
{ | |
SS = new List<string> | |
{ | |
oneString, twoString, threeString | |
} | |
}; | |
AwsDynamoDbClient | |
.PutItemAsync( | |
new PutItemRequest | |
{ | |
TableName = tableName, Item = initialUploadedItem | |
}) | |
.Wait(); | |
// verify that the updated object was stored as expected | |
var updatedUploadedItem = AwsDynamoDbClient | |
.GetItemAsync( | |
new GetItemRequest | |
{ | |
TableName = tableName, | |
Key = new Dictionary<string, AttributeValue> | |
{ | |
{ | |
keyName, new AttributeValue | |
{ | |
S = testKeyValue | |
} | |
} | |
} | |
}) | |
.Result | |
.Item; | |
Assert.AreEqual(testKeyValue, updatedUploadedItem[keyName].S); | |
Assert.AreEqual(updatedStringValue, updatedUploadedItem[stringValueKey].S); | |
Assert.AreEqual(3, updatedUploadedItem[stringListKey].L.Count); | |
Assert.AreEqual(twoString, updatedUploadedItem[stringListKey].L[1].S); | |
Assert.AreEqual(threeString, updatedUploadedItem[stringListKey].L[2].S); | |
Assert.AreEqual(3, updatedUploadedItem[stringSetKey].SS.Count); | |
Assert.IsTrue(updatedUploadedItem[stringSetKey].SS.IndexOf(twoString) > -1); | |
Assert.IsTrue(updatedUploadedItem[stringSetKey].SS.IndexOf(threeString) > -1); | |
Assert.AreEqual(oneNumeric, updatedUploadedItem[numberMapKey].M[oneString].N); | |
Assert.AreEqual(true, updatedUploadedItem[multilevelMapKey].M[twoString].M[innerKey].BOOL); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment