Использование пакета Azure SDK для Go с таблицами Azure
Область применения: Таблица
Совет
Содержимое этой статьи относится к хранилищу таблиц Azure и Azure Cosmos DB для таблицы. API для таблицы — это предложение уровня "Премиум" для хранилища таблиц, которое предлагает оптимизированные для пропускной способности таблицы, глобальное распределение и автоматические вторичные индексы.
Из этой статьи вы узнаете, как создавать, перечислять и удалять таблицы и сущности таблиц Azure с помощью пакета Azure SDK для Go.
Таблица Azure позволяет хранить структурированные данные NoSQL в облаке, предоставляя хранилище ключей и атрибутов с бессхемной структурой. Бессхемная структура хранилища таблиц Azure позволяет легко адаптировать данные под меняющиеся требования приложений. Доступ к API и данным таблиц — это быстрое и экономичное решение для многих приложений.
Хранилище таблиц или Azure Cosmos DB можно использовать для хранения гибких наборов данных, например пользовательских данных для веб-приложений, адресных книг, сведений об устройстве. Либо метаданных любого другого типа, которые требуются вашей службе. В таблице можно хранить любое количество сущностей, а учетная запись хранения может содержать любое количество таблиц в пределах емкости учетной записи.
Продолжите изучение этой статьи, чтобы узнать, как управлять хранилищем таблиц Azure с помощью пакета Azure SDK для Go.
Необходимые компоненты
- Подписка Azure — создайте бесплатную учетную запись.
- Установленная среда Go: версия 1.17 или выше.
- Azure CLI
Настройка среды
Для работы с этим руководством вам потребуется группа ресурсов Azure, учетная запись хранения и ресурс таблицы. Выполните следующие команды, чтобы настроить среду:
Создайте группу ресурсов Azure.
az group create --name myResourceGroup --location eastus
Затем создайте учетную запись хранения Azure для новой таблицы Azure.
az storage account create --name <storageAccountName> --resource-group myResourceGroup --location eastus --sku Standard_LRS
Создайте ресурс таблицы.
az storage table create --account-name <storageAccountName> --account-key 'storageKey' --name mytable
Установка пакетов
Вам потребуется два пакета для управления таблицей Azure с помощью Go: azidentity и aztables. Пакет azidentity
предоставляет способ проверки подлинности в Azure. Пакеты aztables
предоставляют возможность управлять ресурсом таблиц в Azure. Чтобы установить эти пакеты, выполните следующие команды Go:
go get github.com/Azure/azure-sdk-for-go/sdk/data/aztables
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
Дополнительные сведения о способах проверки подлинности в Azure вы найдете в статье Проверка подлинности с помощью пакета Azure SDK для Go.
Создание примера приложения
После установки пакетов создайте пример приложения, использующий пакет Azure SDK для Go, чтобы управлять таблицей Azure. Выполните команду go mod
, чтобы создать новый модуль с именем azTableSample
.
go mod init azTableSample
Затем создайте файл с именем main.go
и скопируйте в него следующий код:
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/Azure/azure-sdk-for-go/sdk/data/aztables"
)
type InventoryEntity struct {
aztables.Entity
Price float32
Inventory int32
ProductName string
OnSale bool
}
type PurchasedEntity struct {
aztables.Entity
Price float32
ProductName string
OnSale bool
}
func getClient() *aztables.Client {
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT")
if !ok {
panic("AZURE_STORAGE_ACCOUNT environment variable not found")
}
tableName, ok := os.LookupEnv("AZURE_TABLE_NAME")
if !ok {
panic("AZURE_TABLE_NAME environment variable not found")
}
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
panic(err)
}
serviceURL := fmt.Sprintf("https://%s.table.core.windows.net/%s", accountName, tableName)
client, err := aztables.NewClient(serviceURL, cred, nil)
if err != nil {
panic(err)
}
return client
}
func createTable(client *aztables.Client) {
//TODO: Check access policy, Storage Blob Data Contributor role needed
_, err := client.Create(context.TODO(), nil)
if err != nil {
panic(err)
}
}
func addEntity(client *aztables.Client) {
myEntity := InventoryEntity{
Entity: aztables.Entity{
PartitionKey: "pk001",
RowKey: "rk001",
},
Price: 3.99,
Inventory: 20,
ProductName: "Markers",
OnSale: false,
}
marshalled, err := json.Marshal(myEntity)
if err != nil {
panic(err)
}
_, err = client.AddEntity(context.TODO(), marshalled, nil) // TODO: Check access policy, need Storage Table Data Contributor role
if err != nil {
panic(err)
}
}
func listEntities(client *aztables.Client) {
listPager := client.List(nil)
pageCount := 0
for listPager.More() {
response, err := listPager.NextPage(context.TODO())
if err != nil {
panic(err)
}
fmt.Printf("There are %d entities in page #%d\n", len(response.Entities), pageCount)
pageCount += 1
}
}
func queryEntity(client *aztables.Client) {
filter := fmt.Sprintf("PartitionKey eq '%v' or RowKey eq '%v'", "pk001", "rk001")
options := &aztables.ListEntitiesOptions{
Filter: &filter,
Select: to.StringPtr("RowKey,Price,Inventory,ProductName,OnSale"),
Top: to.Int32Ptr(15),
}
pager := client.List(options)
for pager.More() {
resp, err := pager.NextPage(context.Background())
if err != nil {
panic(err)
}
for _, entity := range resp.Entities {
var myEntity PurchasedEntity
err = json.Unmarshal(entity, &myEntity)
if err != nil {
panic(err)
}
fmt.Println("Return custom type [PurchasedEntity]")
fmt.Printf("Price: %v; ProductName: %v; OnSale: %v\n", myEntity.Price, myEntity.ProductName, myEntity.OnSale)
}
}
}
func deleteEntity(client *aztables.Client) {
_, err := client.DeleteEntity(context.TODO(), "pk001", "rk001", nil)
if err != nil {
panic(err)
}
}
func deleteTable(client *aztables.Client) {
_, err := client.Delete(context.TODO(), nil)
if err != nil {
panic(err)
}
}
func main() {
fmt.Println("Authenticating...")
client := getClient()
fmt.Println("Creating a table...")
createTable(client)
fmt.Println("Adding an entity to the table...")
addEntity(client)
fmt.Println("Calculating all entities in the table...")
listEntities(client)
fmt.Println("Querying a specific entity...")
queryEntity(client)
fmt.Println("Deleting an entity...")
deleteEntity(client)
fmt.Println("Deleting a table...")
deleteTable(client)
}
Внимание
Убедитесь, что у учетной записи, с которой вы прошли проверку подлинности, есть соответствующая политика доступа для управления учетной записью хранения Azure. Чтобы выполнить приведенный выше код, вашей учетной записи должна быть назначена как минимум роль "Участник для данных BLOB-объектов хранилища" и роль "Участник плоскости данных таблиц хранилища".
Примеры кода
аутентификация клиента;
// Lookup environment variables
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT")
if !ok {
panic("AZURE_STORAGE_ACCOUNT environment variable not found")
}
tableName, ok := os.LookupEnv("AZURE_TABLE_NAME")
if !ok {
panic("AZURE_TABLE_NAME environment variable not found")
}
// Create a credential
cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
panic(err)
}
// Create a table client
serviceURL := fmt.Sprintf("https://%s.table.core.windows.net/%s", accountName, tableName)
client, err := aztables.NewClient(serviceURL, cred, nil)
if err != nil {
panic(err)
}
Создание таблицы
// Create a table and discard the response
_, err := client.Create(context.TODO(), nil)
if err != nil {
panic(err)
}
Создание сущности
// Define the table entity as a custom type
type InventoryEntity struct {
aztables.Entity
Price float32
Inventory int32
ProductName string
OnSale bool
}
// Define the entity values
myEntity := InventoryEntity{
Entity: aztables.Entity{
PartitionKey: "pk001",
RowKey: "rk001",
},
Price: 3.99,
Inventory: 20,
ProductName: "Markers",
OnSale: false,
}
// Marshal the entity to JSON
marshalled, err := json.Marshal(myEntity)
if err != nil {
panic(err)
}
// Add the entity to the table
_, err = client.AddEntity(context.TODO(), marshalled, nil) // needs Storage Table Data Contributor role
if err != nil {
panic(err)
}
Получение сущности
// Define the new custom type
type PurchasedEntity struct {
aztables.Entity
Price float32
ProductName string
OnSale bool
}
// Define the query filter and options
filter := fmt.Sprintf("PartitionKey eq '%v' or RowKey eq '%v'", "pk001", "rk001")
options := &aztables.ListEntitiesOptions{
Filter: &filter,
Select: to.StringPtr("RowKey,Price,Inventory,ProductName,OnSale"),
Top: to.Int32Ptr(15),
}
// Query the table for the entity
pager := client.List(options)
for pager.More() {
resp, err := pager.NextPage(context.Background())
if err != nil {
panic(err)
}
for _, entity := range resp.Entities {
var myEntity PurchasedEntity
err = json.Unmarshal(entity, &myEntity)
if err != nil {
panic(err)
}
fmt.Println("Return custom type [PurchasedEntity]")
fmt.Printf("Price: %v; ProductName: %v; OnSale: %v\n", myEntity.Price, myEntity.ProductName, myEntity.OnSale)
}
}
Удаление сущности
_, err := client.DeleteEntity(context.TODO(), "pk001", "rk001", nil)
if err != nil {
panic(err)
}
Удалить таблицу
_, err := client.Delete(context.TODO(), nil)
if err != nil {
panic(err)
}
Выполнение кода
Теперь осталось запустить приложение. Но перед этим необходимо настроить переменные среды. Создайте две переменные среды и присвойте им соответствующее значение с помощью следующих команд:
export AZURE_STORAGE_ACCOUNT=<YourStorageAccountName>
export AZURE_TABLE_NAME=<YourAzureTableName>
Выполните следующую команду go run
, чтобы запустить приложение:
go run main.go
Очистка ресурсов
Чтобы удалить группу ресурсов и все ее оставшиеся ресурсы, выполните следующую команду.
az group delete --resource-group myResourceGroup
Следующие шаги
Из этого краткого руководства вы узнали, как создать учетную запись Azure Cosmos DB и таблицу с помощью обозревателя данных, а также как запустить приложение. Теперь вы можете запросить данные с помощью API для таблицы.