1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Alexaスキル(C#)からDynamoDBにアクセスするには?(データの追加)

Posted at

はじめに

C#でDynamoDBにテーブルを作りました

今回はそこにデータを追加してみます。

データの追加の流れ

テーブルにデータの追加を行うにはAmazonDynamoDBClientクラスのPutItemAsyncメソッドを使用します。
PutItemAsyncメソッドにPutItemRequestクラスのインスタンスを渡すと、そのインスタンスに入れたデータを指定したテーブルに入れることができます。

ですので流れは以下のとおりになります。

  1. PutItemRequestのインスタンスにテーブル名と各カラムのデータを登録
  2. PutItemAsyncメソッドにPutItemRequestインスタンスを引数として渡して実行

ソースコードはこんな感じです。

            //データを挿入するリクエストを構築
            var request = new PutItemRequest
            {
                //追加先のテーブル名を指定
                TableName = tableName,
                //各カラムに入れるデータを指定
                Item = new Dictionary<string, AttributeValue>
                {
                    //「ThisIsId」カラムに「2」という数値を入れる
                    {"ThisIsId",new AttributeValue{N="2"} },
                    //「ThisIsSomething」カラムに「5」という数値を入れる
                    {"ThisIsSomething",new AttributeValue{N="5"} }
                }
            };

            var client = AmazonDynamoDBClient();

            //目的のテーブルに所定のデータを追加
            var result = client.PutItemAsync(request).Result;

まず、リクエストの構築です。
ここでカラムに入れる値を指定してます。
その中で「N="2"」などとしていますが、これは数値としての「2」を入れるという意味です。
「N」はデータの種類を表しているということですね。
「N」の他にも「S:文字列(String)」や「SS:文字列のリスト」、「NS:数値のリスト」などが指定できます。

テーブルを作成するときにAttributeTypeとして「N」を指定しましたが、それと同じ指定をしてください。
ちなみにその記事を書いたときは意味がわかっていませんでした。

追加してみましょう

ということで、以上を踏まえてテーブルにデータを追加してみます。
データを追加する処理をPutItemというメソッドとして切り出してあります。
今回は、このメソッドの中で追加するデータを直接指定していますが、実用性を考えるのであれば追加するデータを引数として受け取るようにすると良いでしょう。

Function.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Alexa.NET.Request;
using Alexa.NET.Response;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;


// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace DynamoDBTest
{
    public class Function
    {
        /// <summary>
        /// A simple function that takes a string and does a ToUpper
        /// </summary>
        /// <param name="input"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public SkillResponse FunctionHandler(SkillRequest input, ILambdaContext context)
        {
            //ここにDynamoDBにアクセスするコードを追加していく
            string tableName = "TestTable";//テーブル名
            AmazonDynamoDBClient client = new AmazonDynamoDBClient();//主役。これを介してDynamoDBにアクセスする

            //同名テーブルの存在確認
            if (!IsTableExist(client, tableName))
            {
                //テーブルを作成
                CreateTable(client, tableName);
            }

            PutItem(client, tableName);

            return new SkillResponse
            {
                Version = "1.0",
                Response = new ResponseBody()
            };
        }


        /// <summary>
        /// DynamoDBにテーブルを作成する
        /// </summary>
        /// <param name="client"></param>
        /// <param name="tableName"></param>
        private void CreateTable(IAmazonDynamoDB client, string tableName)
        {
            //リクエストを構築
            var request = new CreateTableRequest
            {
                //テーブルの列情報を設定
                //「ThisIsId」と「ThisIsSomthing」という2つの列を持つテーブルを作る
                AttributeDefinitions = new List<AttributeDefinition>()
                {
                    new AttributeDefinition
                    {
                        AttributeName = "ThisIsId",//カラム名
                        AttributeType = "N"//データのタイプ:N:数値、S:文字列、他にもいくつか。勉強中
                    },
                    new AttributeDefinition
                    {
                        AttributeName = "ThisIsSomething",//カラム名
                        AttributeType = "N"//データのタイプ:N:数値、S:文字列、他にもいくつか。勉強中
                    }
                },
                //勉強中
                KeySchema = new List<KeySchemaElement>
                {
                    new KeySchemaElement
                    {
                        AttributeName = "ThisIsId",
                        KeyType = KeyType.HASH //Partition key
                    },
                    new KeySchemaElement
                    {
                        AttributeName = "ThisIsSomething",
                        KeyType = KeyType.RANGE,//Sort key
                    }
                },
                //勉強中
                ProvisionedThroughput = new ProvisionedThroughput
                {
                    ReadCapacityUnits = 5,
                    WriteCapacityUnits = 5
                },
                //テーブル名
                TableName = tableName
            };

            //テーブル作成リクエストを投げる!
            //ただし、非同期メソッドの返りを待たねければならない。
            //待たないと先にこのLambdaが終了して、DynamoDBのテーブル作成処理を完了せずに終わる。
            //でもメソッドにasyncつけたら、最終的にスキルのレスポンスの型もTask<SkillResponse>にしなきゃいけなくなってだめ。
            //.Wait()メソッドで非同期メソッドを同期メソッドにしちゃえば、返り値も変えなくていいし、テーブル作成完了まで待つことができる。
            //一回完結のサーバー側の処理で非同期でなきゃいけない理由ないしね。
            //client.CreateTableAsync(request).Wait();

            //Waitメソッドではただ非同期メソッドの完了を待つだけでしたが、非同期メソッドの返り値を取得したい場合は、Resultプロパティを使いましょう。
            //Resultプロパティにアクセスすることで、非同期メソッドの完了を待った上で結果を取得することができます。
            //結果を使って何か処理を行いたい場合はこちらが良いのではないでしょうか。
            var result = client.CreateTableAsync(request).Result;
        }


        /// <summary>
        /// 同名のテーブルが存在するかをチェックします。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private bool IsTableExist(IAmazonDynamoDB client, string tableName)
        {
            //テーブル一覧を取得
            var tableList = client.ListTablesAsync().Result;
            //TableNamesプロパティをチェック
            return tableList.TableNames.Exists(s => s.Equals(tableName));
        }


        /// <summary>
        /// データをテーブルに追加します。
        /// </summary>
        /// <param name="client"></param>
        /// <param name="tableName"></param>
        private void PutItem(IAmazonDynamoDB client, string tableName)
        {
            //リクエストの構築
            var request = new PutItemRequest
            {
                TableName = tableName,//追加先のテーブル名
                //各カラムの値を指定
                Item = new Dictionary<string, AttributeValue>
                {
                    {"ThisIsId",new AttributeValue{N= "2"} },
                    {"ThisIsSomething",new AttributeValue{N="5"} }
                }
            };

            //テーブルに追加
            var result = client.PutItemAsync(request).Result;
        }
    }
}

前回と同じようにデプロイしてテストしてみましょう。
AWSコンソールで確認してみると、以下のようにデータが追加されていることが確認できます。

image.png

おわりに

テーブルへのデータの追加の流れと基本的な方法について、少し理解が進みました。
しかしこれは単純なデータの追加だけですので、Alexaスキルでデータの保持に使用するにはまだ足りないことばかりです。
が、次はこれをもとに公式チュートリアル第4回をC#でやってみようと思います。
その試行錯誤によって更に理解が進むものと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?