Uso de bases de datos NoSQL de Amazon DynamoDB - AWS SDK for .NET

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Uso de bases de datos NoSQL de Amazon DynamoDB

nota

Los modelos de programación de estos temas están presentes tanto en .NET Framework como en .NET (Core), pero las convenciones de llamada difieren entre sincrónicas y asincrónicas.

AWS SDK for .NET Es compatible con Amazon DynamoDB, que es un servicio rápido de base de datos NoSQL ofrecido por. AWS SDK proporciona tres modelos de programación para comunicarse con DynamoDB: el modelo de bajo nivel, el modelo de documento y el modelo de persistencia de objetos.

En la siguiente información se presentan estos modelos y sus API, se proporcionan ejemplos acerca de cómo y cuándo usarlos y se facilitan enlaces a más recursos de programación de DynamoDB en AWS SDK for .NET.

Modelo de bajo nivel

El modelo de programación de bajo nivel incluye llamadas directas al servicio DynamoDB. Puede obtener acceso a este modelo a través del espacio de nombres Amazon.DynamoDBv2.

De los tres modelos, el de bajo nivel requiere que escriba la mayor parte del código. Por ejemplo, debe convertir los tipos de datos de .NET en sus equivalentes en DynamoDB. Sin embargo, este modelo le ofrece acceso a la mayoría de las características.

En el siguiente ejemplo se muestra cómo usar el modelo de bajo nivel para crear una tabla, modificarla e insertar elementos en ella en DynamoDB.

Creación de una tabla

En el siguiente ejemplo, puede crear una tabla mediante el método CreateTable de la clase AmazonDynamoDBClient. El método CreateTable usa una instancia de la clase CreateTableRequest que contiene características como los nombres de atributos de elemento obligatorios, la definición de clave principal y la capacidad de desempeño. El método CreateTable devuelve una instancia de la clase CreateTableResponse.

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); Console.WriteLine("Getting list of tables"); List<string> currentTables = client.ListTables().TableNames; Console.WriteLine("Number of tables: " + currentTables.Count); if (!currentTables.Contains("AnimalsInventory")) { var request = new CreateTableRequest { TableName = "AnimalsInventory", AttributeDefinitions = new List<AttributeDefinition> { new AttributeDefinition { AttributeName = "Id", // "S" = string, "N" = number, and so on. AttributeType = "N" }, new AttributeDefinition { AttributeName = "Type", AttributeType = "S" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", // "HASH" = hash key, "RANGE" = range key. KeyType = "HASH" }, new KeySchemaElement { AttributeName = "Type", KeyType = "RANGE" }, }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 10, WriteCapacityUnits = 5 }, }; var response = client.CreateTable(request); Console.WriteLine("Table created with request ID: " + response.ResponseMetadata.RequestId); }

Verificación de la preparación de una tabla para su modificación

Antes de poder cambiar o modificar una tabla, esta debe estar lista para ello. En el siguiente ejemplo se muestra cómo usar el modelo de bajo nivel para verificar que una tabla de DynamoDB está lista. En este ejemplo, se hace referencia a la tabla de destino que se comprobará a través del método DescribeTable de la clase AmazonDynamoDBClient. Cada cinco segundos, el código comprueba el valor de la propiedad TableStatus de la tabla. Cuando el estado se establezca en ACTIVE, la tabla estará lista para modificarse.

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var status = ""; do { // Wait 5 seconds before checking (again). System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5)); try { var response = client.DescribeTable(new DescribeTableRequest { TableName = "AnimalsInventory" }); Console.WriteLine("Table = {0}, Status = {1}", response.Table.TableName, response.Table.TableStatus); status = response.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. } } while (status != TableStatus.ACTIVE);

Inserción de un elemento en una tabla

En el siguiente ejemplo se usa el modelo de bajo nivel para insertar dos elementos en una tabla de DynamoDB. Cada elemento se inserta a través del método PutItem de la clase AmazonDynamoDBClient, mediante una instancia de la clase PutItemRequest. Cada una de las dos instancias de la clase PutItemRequest toma el nombre de la tabla en la que se insertarán los elementos, con una serie de valores de atributos de elemento.

// using Amazon.DynamoDBv2; // using Amazon.DynamoDBv2.Model; var client = new AmazonDynamoDBClient(); var request1 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "1" }}, { "Type", new AttributeValue { S = "Dog" }}, { "Name", new AttributeValue { S = "Fido" }} } }; var request2 = new PutItemRequest { TableName = "AnimalsInventory", Item = new Dictionary<string, AttributeValue> { { "Id", new AttributeValue { N = "2" }}, { "Type", new AttributeValue { S = "Cat" }}, { "Name", new AttributeValue { S = "Patches" }} } }; client.PutItem(request1); client.PutItem(request2);

Modelo de documento

El modelo de programación del documento proporciona una forma más sencilla de trabajar con datos en DynamoDB. Este modelo está destinado de manera específica al acceso a tablas y elementos de las tablas. Puede acceder a este modelo a través de Amazon.DynamoDBv2. DocumentModelespacio de nombres.

En comparación con el modelo de programación de bajo nivel, es más sencillo escribir el código del modelo de documento en los datos de DynamoDB. Por ejemplo, no debe convertir tantos tipos de datos de .NET en sus equivalentes en DynamoDB. Sin embargo, este modelo no proporciona acceso a tantas características como el modelo de programación de bajo nivel. Por ejemplo, puede usar este modelo para crear, recuperar, actualizar y eliminar elementos de las tablas. No obstante, para crear las tablas, debe usar el modelo de bajo nivel. En comparación con el modelo de persistencia de objetos, este modelo requiere que escriba más código para almacenar, cargar y consultar objetos de .NET.

Para obtener más información sobre el modelo de programación de documentos de DynamoDB, consulte .NET: modelo de documento en la Guía para desarrolladores de Amazon DynamoDB.

En las siguientes secciones se proporciona información sobre cómo crear una representación de la tabla de DynamoDB deseada, así como ejemplos sobre cómo utilizar el modelo de documento para insertar elementos en tablas y obtener elementos de tablas.

Creación de una representación de la tabla

Para llevar a cabo operaciones de datos con el modelo de documento, primero hay que crear una instancia de la clase Table que representa una tabla específica. Principalmente, hay dos formas de hacer esto.

LoadTable método

El primer mecanismo consiste en utilizar uno de los métodos LoadTable estáticos de la clase Table, similar al ejemplo siguiente:

var client = new AmazonDynamoDBClient(); Table table = Table.LoadTable(client, "Reply");
nota

Aunque este mecanismo funciona, hay veces que, bajo determinadas condiciones, puede provocar más latencias o interbloqueos debido a comportamientos de inicio en frío y de grupo de subprocesos. Para obtener más información sobre estos comportamientos, consulte la entrada de blog Improved DynamoDB Initialization Patterns for AWS SDK for .NET.

TableBuilder

En la versión 3.7.203 del TableBuilderpaquete AWSSDK NuGet .DynamoDBV2 se introdujo un mecanismo alternativo, la clase. Este mecanismo aborda los comportamientos mencionados anteriormente, ya que elimina ciertas llamadas a método implícitas, en concreto, el método DescribeTable. Este mecanismo se utiliza de forma similar a la del siguiente ejemplo:

var client = new AmazonDynamoDBClient(); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build();

Para obtener más información sobre este mecanismo alternativo, consulte la entrada de blog Patrones de inicialización de DynamoDB mejorados para AWS SDK for .NET.

Inserción de un elemento en una tabla

En el siguiente ejemplo se inserta una respuesta en la tabla Reply a través del método PutItemAsync de la clase Table. El método PutItemAsync toma una instancia de la clase Document; la clase Document es sencillamente una colección de atributos inicializados.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, add a reply to the table. var newReply = new Document(); newReply["Id"] = Guid.NewGuid().ToString(); newReply["ReplyDateTime"] = DateTime.UtcNow; newReply["PostedBy"] = "Author1"; newReply["Message"] = "Thank you!"; await table.PutItemAsync(newReply);

Obtención de un elemento de una tabla

En el siguiente ejemplo se recupera una respuesta a través del método GetItemAsync de la clase Table. Para determinar la respuesta que se va a obtener, el GetItemAsync método utiliza la clave hash-and-range principal de la respuesta de destino.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DocumentModel; // Create a representation of the "Reply" table // by using one of the mechanisms described previously. // Then, get a reply from the table // where "guid" is the hash key and "datetime" is the range key. var reply = await table.GetItemAsync(guid, datetime); Console.WriteLine("Id = " + reply["Id"]); Console.WriteLine("ReplyDateTime = " + reply["ReplyDateTime"]); Console.WriteLine("PostedBy = " + reply["PostedBy"]); Console.WriteLine("Message = " + reply["Message"]);

En el ejemplo anterior, los valores de la tabla se convierten de forma implícita en cadenas para el método WriteLine. Puede realizar conversiones explícitas mediante los diversos métodos “As[type]” de la clase DynamoDBEntry. Por ejemplo, puede convertir el valor de atributo de Id de forma explícita a partir de un tipo de datos Primitive en un GUID a través del método AsGuid():

var guid = reply["Id"].AsGuid();

Modelo de persistencia de objetos

El modelo de programación de persistencia de objetos está diseñado de forma específica para almacenar, cargar y consultar objetos de .NET en DynamoDB. Puede acceder a este modelo a través de Amazon.DynamoDBv2. DataModelespacio de nombres.

De los tres modelos, lo más sencillo es escribir el código del modelo de persistencia de objetos siempre que almacene, cargue o consulte los datos de DynamoDB. Por ejemplo, puede trabajar directamente con los tipos de datos de DynamoDB. Sin embargo, este modelo proporciona acceso únicamente a las operaciones que almacenan, cargan y consultan objetos de .NET en DynamoDB. Por ejemplo, puede usar este modelo para crear, recuperar, actualizar y eliminar elementos de las tablas. Sin embargo, primero debe crear sus tablas con el modelo de bajo nivel y, a continuación, utilizar este modelo para asignar las clases de .NET a las tablas.

Para obtener más información sobre el modelo de programación de persistencia de objetos de DynamoDB, consulte .NET: modelo de persistencia de objetos en la Guía para desarrolladores de Amazon DynamoDB.

En los siguientes ejemplos se muestra cómo definir una clase de .NET que representa un elemento de DynamoDB, cómo usar una instancia de la clase de .NET para insertar un elemento de DynamoDB y cómo usar una instancia de la clase de .NET para obtener un elemento de DynamoDB de una tabla.

Definición de una clase de .NET que representa un elemento en una tabla

En el siguiente ejemplo de definición de clase, el DynamoDBTable atributo especifica el nombre de la tabla, mientras que los DynamoDBRangeKey atributos DynamoDBHashKey y modelan la clave hash-and-range principal de la tabla. El atributo DynamoDBGlobalSecondaryIndexHashKey se define de forma que se pueda crear una consulta para obtener respuestas de un autor específico.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] public string Id { get; set; } [DynamoDBRangeKey(StoreAsEpoch = false)] public DateTime ReplyDateTime { get; set; } [DynamoDBGlobalSecondaryIndexHashKey("PostedBy-Message-Index", AttributeName ="PostedBy")] public string Author { get; set; } [DynamoDBGlobalSecondaryIndexRangeKey("PostedBy-Message-Index")] public string Message { get; set; } }

Creación de un contexto para el modelo de persistencia de objetos

Para utilizar el modelo de programación de persistencia de objetos de DynamoDB, debe crear un contexto que ofrezca una conexión a DynamoDB y que permita obtener acceso a las tablas, realizar diversas operaciones y ejecutar consultas.

Contexto básico

En el siguiente ejemplo de código se muestra cómo crear el contexto más básico.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);

Contexto con DisableFetchingTableMetadata propiedad

En el siguiente ejemplo se muestra cómo se podría establecer también la propiedad DisableFetchingTableMetadata de la clase DynamoDBContextConfig para evitar llamadas implícitas al método DescribeTable.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client, new DynamoDBContextConfig { DisableFetchingTableMetadata = true });

Si la propiedad DisableFetchingTableMetadata está establecida en false (valor predeterminado), como se muestra en el primer ejemplo, puede omitir de la clase Reply los atributos que describan la estructura de clave e índice de los elementos de la tabla. En su lugar, estos atributos se deducirán mediante una llamada implícita al método DescribeTable. Si DisableFetchingTableMetadata se establece en true, como se muestra en el segundo ejemplo, los métodos del modelo de persistencia de objetos (como SaveAsync y QueryAsync) se basan completamente en los atributos definidos en la clase Reply. En tal caso, no se realiza ninguna llamada al método DescribeTable.

nota

Bajo determinadas condiciones, las llamadas al método DescribeTable pueden provocar más latencias o interbloqueos debido a comportamientos de inicio en frío y de grupo de subprocesos. Por este motivo, a veces resulta beneficioso evitar las llamadas a ese método.

Para obtener más información sobre estos comportamientos, consulte la entrada de blog Patrones de inicialización de DynamoDB mejorados para AWS SDK for .NET.

Uso de una instancia de la clase de .NET para insertar un elemento en una tabla

En este ejemplo, se inserta un elemento a través del método SaveAsync de la clase DynamoDBContext, que toma una instancia inicializada de la clase de .NET que representa el elemento

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Create an object that represents the new item. var reply = new Reply() { Id = Guid.NewGuid().ToString(), ReplyDateTime = DateTime.UtcNow, Author = "Author1", Message = "Thank you!" }; // Insert the item into the table. await context.SaveAsync<Reply>(reply, new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" });

Uso de una instancia de una clase de .NET para obtener elementos de una tabla

En este ejemplo, se crea una consulta para encontrar todos los registros de “Author1” mediante el método QueryAsync de la clase DynamoDBContext. Después, los elementos se recuperan mediante el método GetNextSetAsync de la consulta.

using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.DataModel; // Create an appropriate context for the object persistence programming model, // examples of which have been described earlier. // Construct a query that finds all replies by a specific author. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig { IndexName = "PostedBy-Message-index" }); // Display the result. var set = await query.GetNextSetAsync(); foreach (var item in set) { Console.WriteLine("Id = " + item.Id); Console.WriteLine("ReplyDateTime = " + item.ReplyDateTime); Console.WriteLine("PostedBy = " + item.Author); Console.WriteLine("Message = " + item.Message); }

Información adicional sobre el modelo de persistencia de objetos

Los ejemplos y las explicaciones que se muestran arriba incluyen a veces una propiedad de la clase DynamoDBContext llamada DisableFetchingTableMetadata. Esta propiedad, que se introdujo en la versión 3.7.203 del NuGet paquete AWSSDK .DynamoDBv2, permite evitar determinadas condiciones que podrían provocar una latencia adicional o bloqueos debido a los comportamientos de arranque en frío y de grupo de subprocesos. Para obtener más información, consulte la entrada de blog Patrones de inicialización de DynamoDB mejorados para AWS SDK for .NET.

Aquí tiene más información sobre esta propiedad.

  • Esta propiedad se puede establecer globalmente en los archivos app.config o web.config si utiliza .NET Framework.

  • Esta propiedad se puede establecer globalmente con la clase AWSConfigsDynamoDB, como se muestra en el siguiente ejemplo.

    // Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client);
  • En algunos casos, no se pueden agregar atributos de DynamoDB a una clase de .NET; por ejemplo, si la clase está definida en una dependencia. En estos casos, se puede seguir sacando partido de la propiedad DisableFetchingTableMetadata. Para ello, utilice la clase TableBuilder además de la propiedad DisableFetchingTableMetadata. La TableBuilder clase también se introdujo en la versión 3.7.203 del paquete .DynamoDBv2. AWSSDK NuGet

    // Set the DisableFetchingTableMetadata property globally // before constructing any context objects. AWSConfigsDynamoDB.Context.DisableFetchingTableMetadata = true; var client = new AmazonDynamoDBClient(); var context = new DynamoDBContext(client); var table = new TableBuilder(client, "Reply") .AddHashKey("Id", DynamoDBEntryType.String) .AddRangeKey("ReplyDateTime", DynamoDBEntryType.String) .AddGlobalSecondaryIndex("PostedBy-Message-index", "Author", DynamoDBEntryType.String, "Message", DynamoDBEntryType.String) .Build(); // This registers the "Reply" table we constructed via the builder. context.RegisterTableDefinition(table); // Now operations like this will work, // even if the Reply class was not annotated with this index. var query = context.QueryAsync<Reply>("Author1", new DynamoDBOperationConfig() { IndexName = "PostedBy-Message-index" });

Más información

Utilización de AWS SDK for .NET para programar información y ejemplos de DynamoDB**

Información y ejemplos del modelo de bajo nivel

Información y ejemplos del modelo de documento

Información y ejemplos del modelo de persistencia de objetos