Compartir a través de


Introducción a Azure Table Storage y a Table API de Azure Cosmos DB mediante F#

Azure Table Storage es un servicio que almacena datos de NoSQL estructurados en la nube. Almacenamiento de tablas es un almacén de claves/atributos con un diseño sin esquema. Como Almacenamiento de tablas carece de esquema, es fácil adaptar los datos a medida que evolucionan las necesidades de la aplicación. El acceso a los datos es rápido y rentable para todos los tipos de aplicaciones y, además, su coste es muy inferior al del SQL tradicional para volúmenes de datos similares.

Table Storage se puede usar para almacenar conjuntos de datos flexibles, como datos de usuarios para aplicaciones web, libretas de direcciones, información de dispositivos y cualquier otro tipo de metadatos requerido por el servicio. Una tabla puede almacenar un número cualquiera de entidades y una cuenta de almacenamiento puede incluir un número cualquiera de tablas, hasta alcanzar el límite de capacidad de este tipo de cuenta.

Azure Cosmos DB proporciona Table API para aplicaciones escritas para Azure Table Storage y que requieren funcionalidades Prémium como:

  • Distribución global llave en mano.
  • Rendimiento dedicado en todo el mundo.
  • Latencias en milisegundos de un solo dígito en el percentil 99.
  • Alta disponibilidad garantizada.
  • Indexación secundaria automática.

Las aplicaciones escritas para Azure Table Storage pueden migrarse a Azure Cosmos DB mediante Table API sin realizar ningún cambio en el código y pueden sacar provecho de las funcionalidades premium. Table API tiene SDK de cliente disponibles para .NET, Java, Python y Node.js.

Para más información, consulte Introducción a Azure Cosmos DB: Table API. Para mayor facilidad, en estos tutoriales se utilizan cadenas de conexión para autenticarse con Azure. Para lograr una seguridad óptima, debe usar Microsoft Entra ID con identidades administradas.

Acerca de este tutorial

En este tutorial se muestra cómo escribir código de F# para realizar algunas tareas comunes mediante Azure Table Storage o Table API de Azure Cosmos DB, tareas entre las cuales se incluye la creación y eliminación de una tabla, y la inserción, actualización, eliminación y consulta de datos de la tabla.

Prerrequisitos

Para usar esta guía, primero debe crear una cuenta de Azure Storage o una cuenta de Azure Cosmos DB.

Creación de un script de F# e inicio interactivo de F#

Los ejemplos de este artículo se pueden usar en una aplicación de F# o en un script de F#. Para crear un script de F#, cree un archivo con la extensión .fsx, por ejemplo, tables.fsx, en el entorno de desarrollo de F#.

Ejecución de scripts

F# interactivo, dotnet fsi, se puede iniciar de forma interactiva o desde la línea de comandos para ejecutar un script. La sintaxis de línea de comandos es

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

Incorporación de paquetes en un script

A continuación, use #rnuget:package name para instalar el paquete Azure.Data.Tables y los espacios de nombres open. Por ejemplo,

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

Incorporación de declaraciones de espacio de nombres

Agregue las siguientes instrucciones open en la parte superior del archivo tables.fsx:

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

Obtención de la cadena de conexión de Azure Storage

Si se conecta al servicio Azure Storage Table, necesitará la cadena de conexión para este tutorial. Puede copiar la cadena de conexión en Azure Portal. Para más información sobre las cadenas de conexión, consulte Configuración de las cadenas de conexión de Azure Storage.

Obtención de la cadena de conexión de Azure Cosmos DB

Si se conecta a Azure Cosmos DB, necesitará la cadena de conexión para este tutorial. Puede copiar la cadena de conexión en Azure Portal. En Azure Portal, en la cuenta de Cosmos DB, vaya a Configuración>Cadena de conexión y seleccione el botón Copiar para copiar la cadena de conexión principal.

En el tutorial, escriba la cadena de conexión en el script como en el siguiente ejemplo:

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

Creación del cliente de Table service

La clase TableServiceClient le permite recuperar las tablas y las entidades en Table Storage. Esta es una forma de crear el cliente de servicio:

let tableClient = TableServiceClient storageConnString

Ahora ya puede escribir código que lee y escribe datos en Almacenamiento de tablas.

Creación de una tabla

En este ejemplo se muestra cómo crear una tabla si todavía no existe:

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

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

Adición de una entidad a una tabla

Una entidad debe tener un tipo que implemente ITableEntity. Puede extender ITableEntity de la manera que quiera, pero el tipo debe tener un constructor sin parámetros. Solo las propiedades que tienen get y set se almacenan en la tabla de Azure.

La clave de partición y la clave de fila de una entidad identifican a dicha entidad de forma inequívoca en la tabla. Las entidades con la misma clave de partición pueden consultarse más rápidamente que aquellas con diferentes claves de partición, pero el uso de claves de partición diversas permite una mayor escalabilidad de las operaciones paralelas.

Este es un ejemplo de un Customer que usa lastName como clave de partición y firstName como clave de fila.

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

Ahora, agregue Customer a la tabla. Para ello, podemos usar el método AddEntity().

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

Inserción de un lote de entidades

Puede insertar un lote de entidades en una tabla mediante una única operación de escritura. Las operaciones por lotes permiten combinar operaciones en una sola ejecución, pero tienen algunas restricciones:

  • Puede realizar actualizaciones, eliminaciones e inserciones en la misma operación por lotes.
  • Una operación por lotes puede incluir hasta 100 entidades.
  • Todas las entidades de una operación por lotes deben compartir la misma clave de partición.
  • Aunque es posible realizar una consulta en una operación por lotes, debe tratarse de la única operación del lote.

Este es un código que combina dos inserciones en una operación por lotes:

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

todas las entidades de una partición

Para consultar una tabla a fin de obtener todas las entidades de una partición, use un objeto Query<T>. En este caso, se filtran las entidades en las que "Smith" es la clave de partición.

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

Recuperación de un rango de entidades de una partición

Si no desea consultar todas las entidades de una partición, puede especificar un rango combinando el filtro de clave de partición con un filtro de clave de fila. Aquí se utilizan dos filtros para obtener todas las entidades de la partición "Smith" en las que la clave de fila (nombre) empieza por una letra anterior a la "M" en el alfabeto.

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

una sola entidad

Para recuperar una sola entidad específica, use GetEntityAsync para especificar el cliente "Ben Smith". En lugar de una colección, se devuelve un Customer. La forma más rápida de recuperar una sola entidad de Table service es especificar las claves de partición y de fila de una consulta.

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

Ahora, puede imprimir los resultados:

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

Actualización de una entidad

Para actualizar una entidad, recupérela de Table service, modifique su objeto y, luego, guarde los cambios de nuevo en Table service mediante una operación TableUpdateMode.Replace. Esto hace que la entidad se reemplace por completo en el servidor, a menos que la entidad del servidor cambiara desde que se recuperó, en cuyo caso la operación dará error. Este error es para evitar que la aplicación sobrescriba accidentalmente los cambios de otros orígenes.

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}"

Actualizar/insertar (upsert) una entidad

A veces, no sabe si existe una entidad en la tabla. Y si lo sabe, los valores actuales almacenados en ella ya no son necesarios. Puede usar el método UpsertEntity para crear la entidad o reemplazarla si existe, independientemente de su estado.

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

Consulta de un subconjunto de propiedades de las entidades

Una consulta de tabla puede recuperar tan solo unas cuantas propiedades de una entidad en lugar de todas ellas. Esta técnica, denominada proyección, puede mejorar el rendimiento de las consultas, en especial en el caso de entidades de gran tamaño. Aquí, solo puede devolver direcciones de correo electrónico mediante Query<T> y Select. No se admite la proyección en el emulador de almacenamiento local, por lo que este código solo se ejecuta cuando está usando una cuenta en Table service.

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

Recuperación de entidades en páginas de forma asincrónica

Si está leyendo un gran número de entidades y desea procesarlas según se van recuperando en lugar de esperar a que se devuelvan todas, puede hacerlo mediante una consulta segmentada. En este caso, puede devolver resultados en páginas mediante un flujo de trabajo asincrónico para que la ejecución no se bloquee mientras espera que se devuelva un conjunto grande de resultados.

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}"

Eliminación de una entidad

Puede eliminar una entidad después de que la haya recuperado. Al igual que con la actualización de una entidad, se producirá un error si la entidad cambia después de su recuperación.

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

Eliminar una tabla

Puede eliminar una tabla de una cuenta de almacenamiento. Después de eliminar una tabla, esta no podrá volver a crearse durante algún tiempo.

table.Delete ()

Vea también