Rozpoczynanie pracy z usługą Azure Table Storage i interfejsem API tabel usługi Azure Cosmos DB przy użyciu języka F#

Azure Table Storage to usługa, która przechowuje ustrukturyzowane dane NoSQL w chmurze. Magazyn tabel jest magazynem kluczy/atrybutów bez schematu. Ponieważ Magazyn tabel nie ma schematu, łatwo zaadaptować dane do rozwijających się potrzeb aplikacji. Dostęp do danych jest szybki i ekonomiczny dla wszystkich rodzajów aplikacji. Magazyn tabel jest zwykle znacznie tańszy niż tradycyjne bazy SQL dla podobnych ilości danych.

Magazyn tabel umożliwia przechowywanie elastycznych zestawów danych, takich jak dane użytkownika dla aplikacji internetowych, książki adresowe, informacje o urządzeniach i wszelkie inne metadane, których wymaga Twoja usługa. W tabeli można przechowywać dowolną liczbę jednostek, a konto magazynu może zawierać dowolną liczbę tabel w granicach pojemności konta magazynu.

Usługa Azure Cosmos DB udostępnia interfejs API tabel dla aplikacji napisanych dla usługi Azure Table Storage i wymagających możliwości premium, takich jak:

  • Gotowa do użytku dystrybucja globalna.
  • Dedykowana przepływność na całym świecie.
  • Opóźnienie rzędu kilku milisekund na poziomie 99. percentyla.
  • Gwarantowana wysoka dostępność.
  • Automatyczne indeksowanie pomocnicze.

Aplikacje napisane dla usługi Azure Table Storage mogą migrować do usługi Azure Cosmos DB przy użyciu interfejsu API tabel bez zmian kodu i korzystać z możliwości premium. Interfejs API tabel zawiera zestawy SDK klientów dostępne dla platform .NET, Java, Python i Node.js.

Aby uzyskać więcej informacji, zobacz Wprowadzenie do interfejsu API tabel usługi Azure Cosmos DB.

Informacje o tym samouczku

W tym samouczku pokazano, jak napisać kod języka F# w celu wykonywania niektórych typowych zadań przy użyciu usługi Azure Table Storage lub interfejsu API tabel usługi Azure Cosmos DB, w tym tworzenia i usuwania tabeli oraz wstawiania, aktualizowania, usuwania i wykonywania zapytań dotyczących danych tabeli.

Wymagania wstępne

Aby użyć tego przewodnika, musisz najpierw utworzyć konto usługi Azure Storage lub konto usługi Azure Cosmos DB.

Tworzenie skryptu języka F# i uruchamianie interaktywnego języka F#

Przykłady w tym artykule mogą być używane w aplikacji języka F# lub skryptu języka F#. Aby utworzyć skrypt języka F#, utwórz plik z .fsx rozszerzeniem, na przykład tables.fsx, w środowisku deweloperów języka F#.

Jak wykonywać skrypty

Program F# Interactive, dotnet fsi, można uruchomić interaktywnie lub można go uruchomić z poziomu wiersza polecenia, aby uruchomić skrypt. Składnia wiersza polecenia to

> dotnet fsi [options] [ script-file [arguments] ]

Dodawanie pakietów w skry skrycie

Następnie użyj polecenia #rnuget:package name , aby zainstalować Azure.Data.Tables pakiet i open przestrzenie nazw. Na przykład

> #r "nuget: Azure.Data.Tables"
open Azure.Data.Tables

Dodawanie deklaracji przestrzeni nazw

Dodaj następujące instrukcje open na początku pliku tables.fsx:

open System
open Azure
open Azure.Data.Tables // Namespace for Table storage types

Uzyskiwanie parametry połączenia usługi Azure Storage

Jeśli łączysz się z usługą Azure Storage Table Service, potrzebujesz parametry połączenia na potrzeby tego samouczka. Możesz skopiować parametry połączenia z witryny Azure Portal. Aby uzyskać więcej informacji na temat parametry połączenia, zobacz Konfigurowanie ciągów Połączenie ion magazynu.

Uzyskiwanie parametry połączenia usługi Azure Cosmos DB

Jeśli łączysz się z usługą Azure Cosmos DB, potrzebujesz parametry połączenia na potrzeby tego samouczka. Możesz skopiować parametry połączenia z witryny Azure Portal. W witrynie Azure Portal na koncie usługi Cosmos DB przejdź do pozycji Ustawienia> Połączenie ion String i wybierz przycisk Kopiuj, aby skopiować ciąg podstawowy Połączenie ion.

W tym samouczku wprowadź parametry połączenia w skry skrycie, podobnie jak w poniższym przykładzie:

let storageConnString = "UseDevelopmentStorage=true" // fill this in from your storage account

Tworzenie klienta usługi table service

Klasa TableServiceClient umożliwia pobieranie tabel i jednostek w usłudze Table Storage. Oto jeden ze sposobów tworzenia klienta usługi:

let tableClient = TableServiceClient storageConnString

Teraz możesz przystąpić do pisania kodu, który będzie odczytywać dane z Magazynu tabel i zapisywać je w nim.

Utwórz tabelę

W tym przykładzie pokazano, jak utworzyć tabelę, jeśli jeszcze nie istnieje:

// Retrieve a reference to the table.
let table = tableClient.GetTableClient "people"

// Create the table if it doesn't exist.
table.CreateIfNotExists () |> ignore

Dodawanie jednostki do tabeli

Jednostka musi mieć typ implementujący ITableEntityelement . Można rozszerzyć ITableEntity w dowolny sposób, ale typ musi mieć konstruktor bez parametrów. Tylko właściwości, które mają zarówno get właściwości, jak i set są przechowywane w tabeli platformy Azure.

Partycja i klucz wiersza jednostki jednoznacznie identyfikują jednostkę w tabeli. Jednostki z tym samym kluczem partycji mogą być przeszukiwane szybciej niż jednostki o różnych kluczach partycji, niemniej użycie różnych kluczy partycji umożliwia zwiększenie skalowalności operacji równoległych.

Oto przykład obiektu Customer , który używa lastName elementu jako klucza partycji i firstName klucza wiersza.

type Customer (firstName, lastName, email: string, phone: string) =
    interface ITableEntity with
        member val ETag = ETag "" with get, set
        member val PartitionKey = "" with get, set
        member val RowKey = "" with get, set
        member val Timestamp = Nullable() with get, set

    new() = Customer(null, null, null, null)
    member val Email = email with get, set
    member val PhoneNumber = phone with get, set
    member val PartitionKey = lastName with get, set
    member val RowKey = firstName with get, set

Teraz dodaj Customer do tabeli. W tym celu możemy użyć metody AddEntity().

let customer = Customer ("Walter", "Harp", "Walter@contoso.com", "425-555-0101")
table.AddEntity customer

Zbiorcze wstawianie jednostek

Można wstawić partię jednostek do tabeli przy użyciu pojedynczej operacji zapisu. Operacje wsadowe umożliwiają łączenie operacji w jednym wykonaniu, ale mają pewne ograniczenia:

  • Można wykonywać aktualizacje, usuwać i wstawiać w tej samej operacji wsadowej.
  • Operacja wsadowa może zawierać maksymalnie 100 jednostek.
  • Wszystkie jednostki w operacji wsadowej muszą mieć ten sam klucz partycji.
  • Chociaż istnieje możliwość wykonania zapytania w operacji wsadowej, musi to być jedyna operacja w partii.

Oto kod, który łączy dwa wstawki w operację wsadową:

let customers =
    [
        Customer("Jeff", "Smith", "Jeff@contoso.com", "425-555-0102")
        Customer("Ben", "Smith", "Ben@contoso.com", "425-555-0103")
    ]

// Add the entities to be added to the batch and submit it in a transaction.
customers
|> List.map (fun customer -> TableTransactionAction (TableTransactionActionType.Add, customer))
|> table.SubmitTransaction

Pobieranie wszystkich jednostek w partycji

Aby wysłać zapytanie do tabeli dla wszystkich jednostek w partycji, użyj Query<T> obiektu . W tym miejscu filtrujesz jednostki, w których element "Smith" jest kluczem partycji.

table.Query<Customer> "PartitionKey eq 'Smith'"

Pobieranie zakresu jednostek w partycji

Jeśli nie chcesz wykonywać zapytania dla wszystkich jednostek w partycji, możesz określić zakres, łącząc filtr klucza partycji z filtrem klucza wiersza. W tym miejscu użyjesz dwóch filtrów, aby pobrać wszystkie jednostki w partycji "Smith", w której klucz wiersza (imię) zaczyna się literą wcześniej niż "M" w alfabecie.

table.Query<Customer> "PartitionKey eq 'Smith' and RowKey lt 'J'"

Pobieranie pojedynczej jednostki

Aby pobrać pojedynczą, konkretną jednostkę, użyj polecenia GetEntityAsync , aby określić klienta "Ben Smith". Zamiast kolekcji można odzyskać Customerelement . Określenie zarówno klucza partycji, jak i klucza wiersza w zapytaniu jest najszybszym sposobem pobrania pojedynczej jednostki z usługi Table Service.

let singleResult = table.GetEntity<Customer>("Smith", "Ben").Value

Wyniki są teraz wyświetlane:

// Evaluate this value to print it out into the F# Interactive console
singleResult

Aktualizowanie jednostki

Aby zaktualizować jednostkę, pobierz ją z usługi Table Service, zmodyfikuj obiekt jednostki, a następnie zapisz zmiany z powrotem w usłudze Table Service przy użyciu TableUpdateMode.Replace operacji. Powoduje to całkowite zastąpienie jednostki na serwerze, chyba że jednostka na serwerze uległa zmianie od czasu jej pobrania, w takim przypadku operacja kończy się niepowodzeniem. Ten błąd uniemożliwia aplikacji nieumyślnie zastępowanie zmian z innych źródeł.

singleResult.PhoneNumber <- "425-555-0103"
try
    table.UpdateEntity (singleResult, ETag "", TableUpdateMode.Replace) |> ignore
    printfn "Update succeeded"
with
| :? RequestFailedException as e ->
    printfn $"Update failed: {e.Status} - {e.ErrorCode}"

Upsert jednostki

Czasami nie wiadomo, czy jednostka istnieje w tabeli. A jeśli tak, bieżące wartości przechowywane w nim nie są już potrzebne. Możesz użyć UpsertEntity metody , aby utworzyć jednostkę lub zastąpić ją, jeśli istnieje, niezależnie od jej stanu.

singleResult.PhoneNumber <- "425-555-0104"
table.UpsertEntity (singleResult, TableUpdateMode.Replace)

Tworzenie zapytania do podzbioru właściwości jednostki

Zapytanie tabeli może pobrać tylko kilka właściwości z jednostki zamiast wszystkich z nich. Ta technika, nazywana projekcją, może poprawić wydajność zapytań, zwłaszcza w przypadku dużych jednostek. W tym miejscu zwracasz tylko adresy e-mail przy użyciu i Query<T>Select. Projekcja nie jest obsługiwana w emulatorze magazynu lokalnego, więc ten kod jest uruchamiany tylko wtedy, gdy używasz konta w usłudze Table Service.

query {
    for customer in table.Query<Customer> () do
    select customer.Email
}

Pobieranie asynchroniczne jednostek na stronach

Jeśli czytasz dużą liczbę jednostek i chcesz przetworzyć je w miarę ich pobierania, zamiast czekać na ich powrót, możesz użyć zapytania segmentowanego. W tym miejscu zwracasz wyniki na stronach przy użyciu przepływu pracy asynchronicznego, aby wykonywanie nie było blokowane podczas oczekiwania na zwrócenie dużego zestawu wyników.

let pagesResults = table.Query<Customer> ()

for page in pagesResults.AsPages () do
    printfn "This is a new page!"
    for customer in page.Values do
        printfn $"customer: {customer.RowKey} {customer.PartitionKey}"

Usuwanie encji

Jednostkę można usunąć po jej pobraniu. Podobnie jak w przypadku aktualizowania jednostki, ten błąd kończy się niepowodzeniem, jeśli jednostka uległa zmianie od czasu jej pobrania.

table.DeleteEntity ("Smith", "Ben")

Usuń tabelę

Tabelę można usunąć z konta magazynu. Usunięta tabela będzie niedostępna do ponownego utworzenia po usunięciu.

table.Delete ()

Zobacz też