{"id":1533,"date":"2021-09-21T08:18:33","date_gmt":"2021-09-21T15:18:33","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sdk\/?p=1533"},"modified":"2022-04-07T06:13:53","modified_gmt":"2022-04-07T13:13:53","slug":"announcing-the-preview-release-for-azure-tables-for-go","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sdk\/announcing-the-preview-release-for-azure-tables-for-go\/","title":{"rendered":"Announcing the Preview Release for Azure Tables for Go"},"content":{"rendered":"<p>We\u2019re excited to announce that the <a href=\"https:\/\/docs.microsoft.com\/azure\/storage\/tables\/\"><strong>Azure Tables<\/strong><\/a> library&#8217;s <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/data\/aztables\">first beta for Go<\/a> is now in preview release. The Azure Table service stores NoSQL data in the cloud with a key\/attribute store schema-less design. The Table storage service can be used to store flexible data sets, such as, user data for web applications, address books, device information, or other types of metadata.<\/p>\n<p>The new libraries follow our <a href=\"https:\/\/aka.ms\/azsdk\/guide\">Azure SDK Guidelines<\/a>, making for an idiomatic, consistent, approachable, diagnosable, and dependable library. The new libraries use the language-specific Azure Core packages for handling requests, errors, and credentials.<\/p>\n<p>Note: The Azure Tables libraries are capable of targeting both Azure Storage Table and <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/table-introduction\">Azure Cosmos DB Table API<\/a> endpoints.<\/p>\n<h2>SDK Availability<\/h2>\n<p>The Azure Tables libraries can be downloaded using:<\/p>\n<pre><code>go get github.com\/Azure\/azure-sdk-for-go\/sdk\/data\/aztables<\/code><\/pre>\n<p>This blog post assumes you have a working developer environment for Go 1.16 and above and you already have an Azure Storage or Cosmos Table account. &#8220;`<\/p>\n<h3>Creating the clients<\/h3>\n<p>There are two clients for interacting with the service. The <code>ServiceClient<\/code> can be used for account-level interactions (creating tables, setting and getting access policies) and the <code>Client<\/code> is used for table-level interactions (create or delete an entity, query, or list entities). You can create clients with an account key, Shared Access Signature, or using a connection string, all of which can be found in the <a href=\"https:\/\/portal.azure.com\">Azure portal<\/a>. Throughout the examples, the <code>handle(err)<\/code> function is used to demonstrate where you can insert your own error handling logic.<\/p>\n<pre><code class=\"language-golang\">cred, err := aztables.NewSharedKeyCredential(\"myAccountName\", \"myAccountKey\")\r\nhandle(err)\r\noptions := &amp;aztables.ClientOptions{} \/\/Optional configuration of the Transporter, Retry policies, Telemetry options, or PerCallOptions\r\nclient, err := aztables.NewClient(\"https:\/\/myAccountName.table.core.windows.net\/myTableName\", cred, options)\r\nhandle(err)\r\n\/\/ ServiceClients can be created in a very similar manner:\r\nserviceClient, err := aztables.NewServiceClient(\"https:\/\/myAccountName.table.core.windows.net\", cred, options)\r\nhandle(err)\r\n\r\n\/\/ You can also use a connection string to create a ServiceClient\r\nserviceClient, err := aztables.NewServiceClientFromConnectionString(\"my-connection-string\", azcore.AnonymousCredential(), options)\r\nhandle(err)<\/code><\/pre>\n<h3>Create a table and add an entity to it<\/h3>\n<p>Table names can be any alphanumeric string between 3 and 63 characters. A table can be created from either the <code>Client<\/code> or the <code>ServiceClient<\/code>, the following snippets will show how to create one from a <code>Client<\/code>.<\/p>\n<p>An Entity can contain up to 255 properties, with the three system properties of <code>PartitionKey<\/code>, <code>RowKey<\/code>, and <code>Timestamp<\/code>. The first two properties must be provided on all entities and the <code>Timestamp<\/code> property will be modified by the service. For more information, see the <a href=\"https:\/\/docs.microsoft.com\/rest\/api\/storageservices\/understanding-the-table-service-data-model#system-properties\">service documentation<\/a>. Entities can only be inserted and queried from the <code>Client<\/code>. Entities are returned via JSON allowing customers to use normal JSON marshaling and unmarshaling techniques (<code>map[string]interface{}<\/code>, <code>map[string]json.RawMessage<\/code>, or a specific struct instance). The <code>aztables<\/code> library also provides an <code>EDMEntity<\/code> struct (and <code>EDMGUID<\/code>, <code>EDMBinary<\/code>, <code>EDMInt64<\/code>, <code>EDMDateTime<\/code> types) to make it easier to parse an entity to an object and to dynamically discover the object&#8217;s fields and data types at runtime.<\/p>\n<p>There are three ways to create an entity: a custom entity, using <code>aztables.Entity<\/code>, and using <code>aztables.EdmEntity<\/code>.<\/p>\n<pre><code class=\"language-golang\">cred, err := aztables.NewSharedKeyCredential(\"myAccountName\", \"myAccountKey\")\r\nhandle(err)\r\nclient, err := aztables.NewClient(\"https:\/\/myAccountName.table.core.windows.net\/myTableName\", cred, nil)\r\nhandle(err)\r\n\r\nresp, err := client.Create(context.Background())\r\nhandle(err)\r\n\r\nmyEntity3 := aztables.EDMEntity{\r\n    Entity: aztables.Entity{\r\n        PartitionKey: \"pencils\",\r\n        RowKey: \"id-003\",\r\n    },\r\n    Properties: map[string]interface{}{\r\n        \"Product\": \"Ticonderoga Pencils\",\r\n        \"Price\": 5.00,\r\n        \"Count\": aztables.EDMInt64(12345678901234),\r\n        \"ProductGUID\": aztables.EDMGUID(\"some-guid-value\"),\r\n        \"DateReceived\": aztables.EDMDateTime(time.Date{....}),\r\n        \"ProductCode\": aztables.EDMBinary([]byte{\"somebinaryvalue\"})\r\n    }\r\n}\r\n\r\nmarshalled3, err := json.Marshal(myEntity3)\r\nhandle(err)\r\n\r\nresp, err := client.AddEntity(context.Background(), marshalled3, nil)\r\nhandle(err)<\/code><\/pre>\n<h3>Querying Table Entities<\/h3>\n<p>The <code>Client<\/code> allows the user to create custom queries using OData filters. Check out the <a href=\"https:\/\/docs.microsoft.com\/rest\/api\/storageservices\/querying-tables-and-entities\">service documentation<\/a> for more information about creating filters.<\/p>\n<pre><code class=\"language-golang\">cred, err := aztables.NewSharedKeyCredential(\"myAccountName\", \"myAccountKey\")\r\nhandle(err)\r\nclient, err := aztables.NewClient(\"https:\/\/myAccountName.table.core.windows.net\/myTableName\", cred, nil)\r\nhandle(err)\r\n\r\nfilter := \"PartitionKey eq 'markers' or RowKey eq 'id-001'\"\r\noptions := &amp;ListEntitiesOptions{\r\n    Filter: &amp;filter,\r\n    Select: to.StringPtr(\"RowKey,Value,Product,Available\"),\r\n    Top: to.Int32Ptr(15),\r\n}\r\n\r\npager := client.List(options)\r\nfor pager.NextPage(context.Background()) {\r\n    resp := pager.PageResponse()\r\n    fmt.Printf(\"Received: %v entitiesn\", len(resp.Entities))\r\n\r\n    for _, entity := range resp.Entities {\r\n        var myEntity aztables.EDMEntity\r\n        err = json.Unmarshal(entity, &amp;myEntity)\r\n        handle(err)\r\n\r\n        fmt.Printf(\"Received: %v, %v, %v, %vn\", myEntity.Properties[\"RowKey\"], myEntity.Properties[\"Value\"], myEntity.Properties[\"Product\"], myEntity.Properties[\"Available\"])\r\n    }\r\n}\r\n\r\nerr := pager.Err()\r\nhandle(err)<\/code><\/pre>\n<h3>Batch Transactions<\/h3>\n<p>The Table service allows multiple entity operations (create, delete, update, and upsert) to be made in a single request using transactional batch operations. The transaction is an &#8220;all-or-nothing&#8221; approach, if there&#8217;s a failure in one of the operations, the entire operation will fail. A transaction can do a combination of create, delete, update, and upsert operations.<\/p>\n<p>Note: All operations within a transaction must target the same partition key. A row key can only be specified once in a transaction.<\/p>\n<pre><code class=\"language-golang\">cred, err := aztables.NewSharedKeyCredential(\"myAccountName\", \"myAccountKey\")\r\nhandle(err)\r\nclient, err := aztables.NewClient(\"https:\/\/myAccountName.table.core.windows.net\/myTableName\", cred, nil)\r\nhandle(err)\r\n\r\nbatch := make([]aztables.TableTransactionAction, 4)\r\n\r\ntype ProductEntity struct {\r\n    aztables.Entity\r\n    Product string\r\n    Price float32\r\n    Brand string\r\n}\r\n\r\nmyentity1 := ProductEntity{\r\n    aztables.Entity: aztables.Entity{\r\n        PartitionKey: \"Marker\",\r\n        RowKey: \"id-001\",\r\n    },\r\n    Product: \"Crayola Markers\",\r\n    Price: 1.99,\r\n    Brand: \"Crayola\",\r\n}\r\nmarshalled1, err := json.Marshal(myEntity1)\r\nhandle(err)\r\nbatch[0] = aztables.TransactionAction{ActionType: aztables.Add, Entity: marshalled1}\r\n\r\nmyentity2 := ProductEntity{\r\n    aztables.Entity: aztables.Entity{\r\n        PartitionKey: \"Pencil\",\r\n        RowKey: \"id-002\",\r\n    },\r\n    Product: \"Classic Pencils\",\r\n    Price: .99,\r\n    Brand: \"Ticonderoga\",\r\n}\r\nmarshalled2, err := json.Marshal(myEntity2)\r\nhandle(err)\r\nbatch[1] = aztables.TransactionAction{ActionType: aztables.Delete, Entity: marshalled2}\r\n\r\nmyentity3 := ProductEntity{\r\n    aztables.Entity: aztables.Entity{\r\n        PartitionKey: \"Pen\",\r\n        RowKey: \"id-003\",\r\n    },\r\n    Product: \"Pilot G2\",\r\n    Price: 4.99,\r\n    Brand: \"Pilot\",\r\n}\r\nmarshalled3, err := json.Marshal(myEntity3)\r\nhandle(err)\r\nbatch[2] = aztables.TransactionAction{ActionType: aztables.InsertMerge, Entity: marshalled3}\r\n\r\nmyentity4 := ProductEntity{\r\n    aztables.Entity: aztables.Entity{\r\n        PartitionKey: \"Eraser\",\r\n        RowKey: \"id-004\",\r\n    },\r\n    Product: \"Expo Eraser\",\r\n    Price: 3.49,\r\n    Brand: \"Expo\",\r\n}\r\nmarshalled4, err := json.Marshal(myEntity4)\r\nhandle(err)\r\nbatch[3] = aztables.TransactionAction{ActionType: aztables.UpdateReplace, Entity: marshalled4}\r\n\r\nresp, err := client.SubmitTransaction(context.Background(), batch, nil)\r\nhandle(err)<\/code><\/pre>\n<h2>Conclusion<\/h2>\n<p>We hope this post was a valuable technical introduction to the <code>Azure Table<\/code> service and what you can use today to build and ship rich experiences. We welcome feedback and suggestions, to submit an issue visit our <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/tree\/main\/sdk\/data\/aztables\">GitHub repository<\/a><\/p>\n<h2>References<\/h2>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/storage\/tables\/\">Official Azure Tables documentation<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/storage\/tables\/table-storage-quickstart-portal\">Create your Tables resources Quickstart<\/a><\/li>\n<\/ul>\n<p><!-- FOOTER: DO NOT EDIT OR REMOVE --><\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/aka.ms\/azsdk\/releases\" target=\"_blank\">Azure SDK Releases<\/a><\/div><\/p>\n<h2>Azure SDK Blog Contributions<\/h2>\n<p>Thank you for reading this Azure SDK blog post!\nWe hope that you learned something new and welcome you to share this post.\nWe are open to Azure SDK blog contributions.\nContact us at <a href=\"mailto:azsdkblog@microsoft.com\">azsdkblog@microsoft.com<\/a> and we&#8217;ll set you up as a guest blogger.<\/p>\n<h2>Azure SDK Links<\/h2>\n<ul>\n<li>Azure SDK Website: <a href=\"https:\/\/aka.ms\/azsdk\">aka.ms\/azsdk<\/a><\/li>\n<li>Azure SDK Intro (3-minute video): <a href=\"https:\/\/aka.ms\/azsdk\/intro\">aka.ms\/azsdk\/intro<\/a><\/li>\n<li>Azure SDK Intro Deck (PowerPoint deck): <a href=\"https:\/\/aka.ms\/azsdk\/intro\/deck\">aka.ms\/azsdk\/intro\/deck<\/a><\/li>\n<li>Azure SDK Releases: <a href=\"https:\/\/aka.ms\/azsdk\/releases\">aka.ms\/azsdk\/releases<\/a><\/li>\n<li>Azure SDK Blog: <a href=\"https:\/\/aka.ms\/azsdk\/blog\">aka.ms\/azsdk\/blog<\/a><\/li>\n<li>Azure SDK Twitter: <a href=\"https:\/\/twitter.com\/AzureSDK\">twitter.com\/AzureSDK<\/a><\/li>\n<li>Azure SDK Design Guidelines: <a href=\"https:\/\/aka.ms\/azsdk\/guide\">aka.ms\/azsdk\/guide<\/a><\/li>\n<li>Azure SDKs &amp; Tools: <a href=\"https:\/\/azure.microsoft.com\/downloads\">azure.microsoft.com\/downloads<\/a><\/li>\n<li>Azure SDK Central Repository: <a href=\"https:\/\/github.com\/azure\/azure-sdk#azure-sdk\">github.com\/azure\/azure-sdk<\/a><\/li>\n<li>Azure SDK for .NET: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-net\">github.com\/azure\/azure-sdk-for-net<\/a><\/li>\n<li>Azure SDK for Java: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-java\">github.com\/azure\/azure-sdk-for-java<\/a><\/li>\n<li>Azure SDK for Python: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-python\">github.com\/azure\/azure-sdk-for-python<\/a><\/li>\n<li>Azure SDK for JavaScript\/TypeScript: <a href=\"https:\/\/github.com\/azure\/azure-sdk-for-js\">github.com\/azure\/azure-sdk-for-js<\/a><\/li>\n<li>Azure SDK for Android: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-android\">github.com\/Azure\/azure-sdk-for-android<\/a><\/li>\n<li>Azure SDK for iOS: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-ios\">github.com\/Azure\/azure-sdk-for-ios<\/a><\/li>\n<li>Azure SDK for Go: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\">github.com\/Azure\/azure-sdk-for-go<\/a><\/li>\n<li>Azure SDK for C: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-c\">github.com\/Azure\/azure-sdk-for-c<\/a><\/li>\n<li>Azure SDK for C++: <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-cpp\">github.com\/Azure\/azure-sdk-for-cpp<\/a><\/li>\n<\/ul>\n<p><!-- FOOTER: DO NOT EDIT OR REMOVE --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, we&#8217;ll announce that the Azure Tables library is in preview for Go.<\/p>\n","protected":false},"author":63249,"featured_media":1562,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[828,750,747,810,811,738],"class_list":["post-1533","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-sdk","tag-azure-tables","tag-azure-sdk","tag-cosmos","tag-go","tag-golang","tag-storage"],"acf":[],"blog_post_summary":"<p>In this post, we&#8217;ll announce that the Azure Tables library is in preview for Go.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/users\/63249"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/comments?post=1533"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/posts\/1533\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media\/1562"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/media?parent=1533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/categories?post=1533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sdk\/wp-json\/wp\/v2\/tags?post=1533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}