Using Amazon DynamoDb with the AWS.NET API Part 2: code beginnings
January 26, 2015 7 Comments
Introduction
In the previous post we went through the basics of Amazon DynamoDb. It is Amazon’s take on NoSql where you can store unstructured data in the cloud. We talked about primary keys and available data types. We also created and deleted our first table.
In this post we’ll install the .NET SDK and start building some test code.
Note that we’ll be concentrating on showing and explaining the technical code examples related to AWS. We’ll ignore software principles like SOLID and layering so that we can stay focused. It’s your responsibility to organise your code properly. There are numerous posts on this blog that take up topics related to software architecture.
Installing the SDK
If you already have the .NET AWS SDK installed then you can ignore the installation bit of this section. You’ll only need to create a new project in Visual Studio.
The Amazon .NET SDK is available through NuGet. Open Visual Studio 2012/2013 and create a new C# console application called DynamoDbDemo. The purpose of this application will be to demonstrate the different parts of the SDK around DynamoDb. In reality the DynamoDb handler could be any type of application:
- A website
- A Windows/Android/iOS app
- A Windows service
- etc.
…i.e. any application that’s capable of sending HTTP/S requests to a service endpoint. We’ll keep it simple and not waste time with view-related tasks.
Install the following NuGet package:
Preparations
We cannot just call the services within the AWS SDK without proper authentication. This is an important reference page to handle your credentials in a safe way. We’ll the take the recommended approach and create a profile in the SDK Store and reference it from app.config.
This series is not about AWS authentication so we won’t go into temporary credentials but later on you may be interested in that option too. Since we’re programmers and it takes a single line of code to set up a profile we’ll go with the programmatic options. Add the following line to Main:
Amazon.Util.ProfileManager.RegisterProfile("demo-aws-profile", "your access key id", "your secret access key");
I suggest you remove the code from the application later on in case you want to distribute it. Run the application and it should execute without exceptions. Next open app.config and add the appSettings section with the following elements:
<appSettings> <add key="AWSProfileName" value="demo-aws-profile"/> </appSettings>
First demo: reading tables information
We’ll put all our test code into a separate class. Insert a cs file called DynamoDbDemoService. We’ll need a method to build a handle to the service which is of type IAmazonDynamoDB:
private IAmazonDynamoDB GetDynamoDbClient() { return new AmazonDynamoDBClient(RegionEndpoint.EUWest1); }
Note that we didn’t need to provide our credentials here. They will be extracted automatically using the profile name in the config file. You may need to adjust the region according to your preferences or what you selected in the previous part.
Let’s first find out what table names we have in DynamoDb. This is almost a trivial task:
public List<string> GetTablesList() { using (IAmazonDynamoDB client = GetDynamoDbClient()) { ListTablesResponse listTablesResponse = client.ListTables(); return listTablesResponse.TableNames; } }
Notice the return type of “ListTables()”, ListTablesResponse. Request and Response objects are abound in the Amazon SDK, this is one example. There’s actually an overload of ListTables which accepts a ListTablesRequest object. The ListTablesRequest object allows you to set a limit on the number of table names returned:
public List<string> GetTablesList() { using (IAmazonDynamoDB client = GetDynamoDbClient()) { ListTablesRequest listTablesRequest = new ListTablesRequest(); listTablesRequest.Limit = 5; ListTablesResponse listTablesResponse = client.ListTables(listTablesRequest); return listTablesResponse.TableNames; } }
Let’s call this from Main:
static void Main(string[] args) { DynamoDbDemoService service = new DynamoDbDemoService(); List<string> dynamoDbTables = service.GetTablesList(); }
If you followed through the previous post or if you already have tables in DynamoDb then the above bit of code should return at least one table name.
So now we can retrieve all table names but we also want to find out some details on each table. The following method will do just that:
public void GetTablesDetails() { List<string> tables = GetTablesList(); using (IAmazonDynamoDB client = GetDynamoDbClient()) { foreach (string table in tables) { DescribeTableRequest describeTableRequest = new DescribeTableRequest(table); DescribeTableResponse describeTableResponse = client.DescribeTable(describeTableRequest); TableDescription tableDescription = describeTableResponse.Table; Debug.WriteLine(string.Format("Printing information about table {0}:", tableDescription.TableName)); Debug.WriteLine(string.Format("Created at: {0}", tableDescription.CreationDateTime)); List<KeySchemaElement> keySchemaElements = tableDescription.KeySchema; foreach (KeySchemaElement schema in keySchemaElements) { Debug.WriteLine(string.Format("Key name: {0}, key type: {1}", schema.AttributeName, schema.KeyType)); } Debug.WriteLine(string.Format("Item count: {0}", tableDescription.ItemCount)); ProvisionedThroughputDescription throughput = tableDescription.ProvisionedThroughput; Debug.WriteLine(string.Format("Read capacity: {0}", throughput.ReadCapacityUnits)); Debug.WriteLine(string.Format("Write capacity: {0}", throughput.WriteCapacityUnits)); List<AttributeDefinition> tableAttributes = tableDescription.AttributeDefinitions; foreach (AttributeDefinition attDefinition in tableAttributes) { Debug.WriteLine(string.Format("Table attribute name: {0}", attDefinition.AttributeName)); Debug.WriteLine(string.Format("Table attribute type: {0}", attDefinition.AttributeType)); } Debug.WriteLine(string.Format("Table size: {0}b", tableDescription.TableSizeBytes)); Debug.WriteLine(string.Format("Table status: {0}", tableDescription.TableStatus)); Debug.WriteLine("===================================================="); } } }
We can extract the details of a table through the DescribeTableRequest object which is passed into the DescribeTable method. The DescribeTable method returns a DescribeTableResponse object which in turn includes another object of type TableDescription. TableDescription holds a number of properties that describe a table in DynamoDb in the selected region. The above code extracts the following properties:
- Creation date
- The key schema, i.e. if the primary key is of type Hash or a composite key of Hash and Range
- The number of records in the table
- The provisioned read and write throughput
- The table attribute names and their types, i.e. string, number or binary
- The table size in bytes
- The table status, i.e. if it’s Active, Creating or Deleting
The TableDescription method also includes properties to check the global and local secondary indexes but I’ve ignored them in the demo.
You can call the above method from Main as follows:
static void Main(string[] args) { DynamoDbDemoService service = new DynamoDbDemoService(); service.GetTablesDetails(); }
Here’s an example output:
Printing information about table Application:
Created at: 2014-10-28 09:53:57
Key name: Id, key type: HASH
Item count: 9
Read capacity: 1
Write capacity: 1
Table attribute name: Id
Table attribute type: S
Table size: 123b
Table status: ACTIVE
You can see that the table attribute name Id is the same as the Key called Id. Attribute type “S” means String – we’ll go through these types in other posts of this series.
In the next post we’ll create a new table and insert records into it in code.
View all posts related to Amazon Web Services and Big Data here.
Reblogged this on Brian By Experience.
I believe return new AmazonDynamoDBClient(RegionEndpoint.EUWest1) throws an error and should be return new AmazonDynamoDBClient(Amazon.RegionEndpoint.EUWest1);
at least with the latest SDK v2
Thanks a lot for your update. //Andras
after following steps you mention I am getting below error during fetch list of tables
An unhandled exception of type ‘Amazon.DynamoDBv2.AmazonDynamoDBException’ occurred in AWSSDK.dll
Additional information: The security token included in the request is invalid.
Please help
Do you have a valid pair of AWS credentials? Do the credentials belong to an AWS user with access to DynamoDb?
Everything fine til here.
Thank you so much for sharing.
I like your approach to explain everything in detail with real examples. I think the ListTables() can’t be used anymore, you can use ListTablesAsync() instead of ListTables(). you didn’t probably have a chance to update this post … .
Thank you for sharing your experience