How to use Windows Azure table storage
Originally published on blog.einbu.no August 3. 2009I found several great articles showing how to work with Windows Azure Table Storage:
- Rob Bagby's Azure Application Part 2: Access Azure Table Storage
- Jim Nakashima's Windows AzureWalkthrough: Table Storage
- Video tutorials on Microsofts Azure developer portal
All these, however, assume that the table storage will be used from an Azure web or worker role. I wanted to see if the Windows Azure Table Store could be used with applications running elsewhere, like on your computer. I'm creating a console application here, but the code can be easily adapted to a WPF, Windows Forms or even an ASP.NET application too.
To follow my instructions, you'll need to download
the Windows Azure SDK from here and install it. You'll also need to unpack the samples.zip
included in the SDK. (Make sure you put it somewhere "writable", ie. not inside
C:\Program Files\Windows Azure SDK\v1.0
where you found it. The Documents (in Vista) or
My Documents folder (in XP or Windows 7) will do fine.)
I'm using the July 2009 CTP of the Azure SDK here...
Create a class library project for our entities and the service class
This part is in about creating our schema and actual table(s).
Start by creating a new class library project to hold the entities classes and the service class. Include references to:
- StorageClient (either include the project in the solution and create a project reference, or precompile it and just include the StorageClient.dll)
- System.Data.Services.Client
In this project, create the entity classes, each of them deriving from the TableStorageEntity class from the Microsoft.Sample.ServiceHosting.StorageClient namespace. This class already supplies the three required fields TimeStamp, PartitionKey and RowKey properties, from which the last two together form the unique key for the entity. This defines a table's schema. We can add on properties to hold the values (columns) we need, like this:
public class Article : TableStorageEntity { public string Title { get; set; } public DateTime Published { get; set; } public string Body { get; set; } }
Next we create the service (or context) class that will allow us to access the entities deriving from TableStorageDataServiceContext (also from the Microsoft.Sample.ServiceHosting.StorageClient namespace.) Here we create properties to expose collections of each entity. (Our table(s))
public class PublicationServiceContext : TableStorageDataServiceContext { public DataServiceQuery Articles { get { return CreateQuery("Articles"); } } }
Note: The property names must match value of the parameter to the CreateQuery call. This is because the tool we use to set up Development Storage uses reflection to find the name of the table, while the data services API (from the System.Data.Service.Client namespace) uses the string passed to the CreateQuery call.
Compile the project. In the next part, we'll use this assembly to set up the development storage.
Prepare development storage to store the entities
Open the Windows Azure SDK Command Prompt, and run the devtablegen.exe utility to create the tables in the development store. Navigate to the folder where your binaries are compiled to, and execute:
devtablegen.exe /forceCreate /database:mydatabasename myassembly.dll
(You decide the name of the database to create in SQL Server, and myassembly.dll is the compiled output from our project.)
Start the Development Storage service, pointing it to the newly created database. You can do this from the Windows Azure SDK Command Prompt like this:
developmentstorage.exe /nogui /database:mydatabasename
You can have a look in your SQL Server now. You'll find that a database was created with the schema defined in our previous assembly.
Note: If Development Storage won't start, it might be due to the fact that its default settings
point to the .SQLEXPRESS instance. If you need to change to another instance, you can use the
dsinit.exe utility for that: dsinit /sqlinstance:.
(including the dot) will point
it to use the default unnamed instance on your computer.
Create the application
Now we're ready to create a simple console app that inserts a new item in our table, and then lists the contents of our table.
Create a new console application project. Include references to:
- StorageClient (as before; either include the project in the solution and create a project reference, or precompile it and just include the StorageClient.dll)
- System.Data.Services.Client
- The class library we made earlier.
In program.cs, we'll write some code to access the table store:
class Program { static void Main(string[] args) { var newArticle = new Article { PartitionKey = "", RowKey = Guid.NewGuid().ToString(), Title = "First article", Body = "Long version of first article", Published = DateTime.Now.Date }; var ctx = new PublicationServiceContext(); ctx.AddObject("Articles", newArticle); ctx.SaveChanges(); foreach (var article in ctx.Articles) { Console.WriteLine("{0} - {1}", article.RowKey, article.Title); } Console.ReadLine(); //Don't close the window 'til someone presses ENTER! } }
Note: When you create the new Article, you'll need to set the PartitionKey and RowKey strings. The SaveChanges statement will crash if any of them is null.
Note 2: With the CTP, there are some differences between the Development Storage and the Azure table storage in the cloud. This is because the Development Storage uses SQL Server 2008 to store its data. Here that means it doesn't support dates before Janury 1., 1753 for the DateTime field, so you must set the Published DateTime to something else than its default value of January 1., year 1. Similiar differences/constraints are found with maximum string lengths.
When table storage is used from an Azure web or worker role, we put the configuration in the .csdef and .cscfg files. Our console application doesn't have these, so we should put this in the app.config instead. (Right click on project, select Add -> New Item... and select Application Configuration File to create it.)
The format/syntax in app.config is different from the .csdef and .cscfg files, so we need to do a slight rewrite to this:
<appSettings> <add key="AccountName" value="devstoreaccount1"/> <add key="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/> <add key="TableStorageEndpoint" value="http://127.0.0.1:10002"/> </appSettings>
The settings used here (including the AccountName and AccountSharedKey), are hardcoded into the development storage. (Meaning it will work on your machine. Just copy and paste from here.) When we're using Azure table storage in the next part, we'll change these.
Compile and run to see it working with the development storage.
Using the real thing: Azure table storage
To set this up with the real Azure, you'll need an Azure account. You can sign up for beta access to Windows Azure by applying here.
Log on to your account and select New Service, then select Storage Account and fill in the blanks on the next page or two. Remember the account name, you'll use it in your application's configuration file. When you've created the account, the page shows you some endpoint addresses and the Primary Access Key. You will need those when configuring your application to use the Windows Azure table storage.
In the app.config file, set the AccountName value to your account name, the AccountShared value to
the Primary Access Key listed. Finally set the TableStorageEndpoint value to the last listed
endpoint value, with the account name stripped. In the beta, this is http://table.core.windows.net
(Rob Bagby has some screenshots
of this in his article. Search for "Consume Table Storage In The Cloud" on that page.)
Now your application knows where the data is. But finally we need to make Azure table storage aware of the structure of the data. That means setting up the tables. Unfortunately, there's no tool like the devtablegen.exe tool we used for setting up the development storage. We're going to do this from code.
We'll create a new console application to set up the tables for us. Include references to:
- StorageClient
- System.Data.Services.Client
- The class library we made earlier.
In program.cs, we'll write some code to access the table store:
class Program { static void Main(string[] args) { var acct = StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration(); TableStorage.CreateTablesFromModel(typeof(PublicationServiceContext), acct); } }
Add the app.config file, and configure the settings for your Windows Azure store:
<appSettings> <add key="AccountName" value="???"/> <add key="AccountSharedKey" value="???"/> <add key="TableStorageEndpoint" value="http://table.core.windows.net"/> </appSettings>
Compile and run. Enjoy!
Now you should be able use Windows Azure table storage in the cloud with your program!