<CF_HOME>/cfusion/bin に移動します。
概要
ColdFusion は、これまで、データの格納および取得はリレーショナルデータベースからのみに制限されていました。ColdFusion の既存のバージョンでは、Hibernate または JDBC ドライバを使用してデータを格納および取得できます。ColdFusion の 2021 リリースでは、NoSQL データベース(DynamoDB など)からデータを格納および取得できます。
Amazon DynamoDB は、あらゆるスケールで 1 桁ミリ秒のパフォーマンスを実現する、キーと値およびドキュメントのデータベースです。インターネット規模のアプリケーションのためのビルトインセキュリティ、バックアップおよび復元、メモリ内キャッシュ機能を備え、完全に管理されたマルチリージョンデータベースです。
DynamoDB を使用すると、あらゆる量のデータを格納および取得し、あらゆるレベルのリクエストトラフィックを提供するデータベーステーブルを作成できます。ダウンタイムやパフォーマンスの低下なしにテーブルのスループット能力をスケールアップまたはスケールダウンでき、AWS マネジメントコンソールを使用してリソース使用率およびパフォーマンス指標を監視できます。
詳しくは、Amazon DynamoDB を参照してください。
DynamoDB でのインデックス作成
Amazon DynamoDB は、プライマリキー値を指定することで、テーブルの項目へのより高速なアクセスを提供します。ただし、多くのアプリケーションは、プライマリキーではなく属性を使用したデータへの効率的なアクセスを可能にするために 1 つまたは複数のセカンダリ(または代替)キーを使用できるようにすることで、メリットを得られる可能性があります。これに対処するために、テーブルに 1 つまたは複数のセカンダリインデックスを作成して、これらのインデックスに対してクエリリクエストを発行できます。
セカンダリインデックスは、テーブルからの属性のサブセットを、クエリ操作をサポートするための代替キーと共に含むデータ構造です。テーブルでクエリを発行するのと同じようにクエリを使用して、インデックスからデータを取得できます。テーブルは、複数のセカンダリインデックスを持つことができます。これにより、アプリケーションは、多くの異なるクエリパターンにアクセスできます。
DynamoDB には、2 種類のセカンダリインデックスがあります。
- グローバルセカンダリインデックス - パーティションキーおよび並べ替えキー(ベーステーブルものものとは異なる可能性がある)を含むインデックス。インデックスに対するクエリが、すべてのパーティションにわたるベーステーブルのすべてのデータに及ぶ可能性があるので、グローバルセカンダリインデックスは「グローバル」と見なされます。
- ローカルセカンダリインデックス - ベーステーブルと同じパーティションキーを持ち、異なる並べ替えキーを持つインデックス。ローカルセカンダリインデックスの各パーティションのスコープは、同じパーティションキー値を持つベーステーブルパーティションであるという意味で、ローカルセカンダリインデックスは「ローカル」です。
サポートされるデータ型
DynamoDB には、サポートするデータ型の定義セットがあります。現在、次のデータ型がサポートされています。
- すべての数値 – N
- すべての文字列 – S
- すべてのブール値 – BOOL
- バイナリ – B
- null – NULL
- リスト – L
- マップ – M
- セット – LS、BS、SS
使用を開始
awsdynamodb モジュールのインストール
Zip インストーラーを使用する場合に限り、Adobe ColdFusion(2021 リリース)はモジュール化されています。デフォルトでは、AWS DynamoDB 用のモジュールはインストールされていません。最初の手順は、DynamoDB パッケージを ColdFusion にインストールすることです。
注意:GUI インストーラーを使用する場合、これらのパッケージは事前にインストールされています。
SNS のパッケージは、awsdynamodb という名前です。
awsdynamodb パッケージをインストールするには、ColdFusion Administrator のパッケージマネージャーページを使用するか、以下の手順に従います。
-
-
次のコマンドを入力します。
- Windows:cfpm.bat
- Linux:cfpm.sh
-
コマンド install awsdynamodb を入力します。
DynamoDB サービスがインストールされるまで待ちます。
DynamoDB にアクセスするための資格情報の取得
AWS を操作する場合、資格情報を検証し、リクエストしているリソースにアクセスするための権限を持っているかどうかをチェックするために、AWS セキュリティ資格情報を指定します。
AWS は、セキュリティ資格情報を使用して、リクエストを認証および承認します。
AWS アクセスキー ID および AWS シークレットアクセスキーを取得する必要があります。詳しくは、アクセスキーを参照してください。
クラウドサービス資格情報
ColdFusion のこのリリースでは、様々なクラウドサービスにアクセスするためのオブジェクトを作成するためにハンドルを提供する新しいメソッド、getCloudService() があります。
サービスハンドルのシンタックスを次に示します。
service=getCloudService(cloudCred,cloudConfig)
- cloudCred:クラウドサービスの資格情報を定義します。構造体または文字列です(資格情報エイリアスとも呼ばれます)。
- cloudConfig:クラウドサービス設定の詳細を定義します。構造体または文字列です(設定エイリアスとも呼ばれます)。
AWS 資格情報を獲得したら、次のいずれかの方法でこれらの資格情報を宣言する必要があります。それによって初めて、これらの資格情報を使用して DynamoDB オブジェクトを作成でき、それからそのオブジェクトを使用して様々な DynamoDB メソッドを呼び出すことができます。
ColdFusion Administrator
資格情報の設定
ColdFusion Administrator で、データとサービス/クラウド資格情報をクリックします。
資格情報エイリアス、ベンダー、資格情報など、次の詳細を入力します。
エイリアスは、クラウドサービスおよびその設定の詳細の名前付き表現です。ColdFusion Administrator を使用して設定エイリアスを設定できます。
詳細を入力したら、「資格情報を追加」をクリックします。
設定オプションの設定
ColdFusion Administrator で、「データとサービス/クラウド設定」をクリックします。
設定エイリアス、ベンダー、サービスの名前など、次の詳細を入力します。
設定オプションを追加した後、さらにいくつかのオプションを追加する必要がある場合があります。次に表示される画面で追加できます。次に、追加する必要がある可能性のあるオプションカテゴリを示します。
- リクエスト設定
- クライアント設定
- プロキシ設定
- 再試行ポリシー
- 再試行条件
オブジェクトの作成
DynamoDB 資格情報および設定オプション用のエイリアスを作成したら、getCloudService API を使用することでオブジェクトを作成できます。例えば、次のように入力します。
dynamoObject = getCloudService("dynamoCred", "dynamoConf")
Application.cfc
Application.cfc で DynamoDB 資格情報および設定オプションを指定できます。次に例を示します。
component { this.name="MyApp" function OnApplicationStart() { application.DynamoProfile = { "credentialAlias" : "Alias Name", "vendorName" : "AWS", "region" : "Region Name", "secretAccessKey" : "Access Secret", "accessKeyId" : "Access Key" } application.DynamoCred = { "serviceName" = "DYNAMODB" } } }
オブジェクトの作成
dynamoObject = getCloudService(application.DynamoProfile, application.DynamoCred)
CFM ページ上
CFM ページでは、次に示す 4 つの方法のいずれかで DynamoDB 資格情報および設定オプションを指定できます。
資格情報エイリアスおよび設定エイリアス
DynamoDB 資格情報および設定オプション用のエイリアスを作成したら、次に示すように、getCloudService ハンドルでそれらのエイリアスを使用できます。
<cfscript> // ColdFusion Administrator で資格情報エイリアスと設定エイリアスを定義 dynamo=getCloudService("dynamoCred","dynamoConf") // アカウントのすべての DynamoDB テーブルをリストアップ listTablesStruct = { "Limit": 50 } listTablesResponse =dynamo.ListTables(listTablesStruct); writeDump(listTablesResponse) </cfscript>
資格情報エイリアスおよび設定オプションの構造体
<cfscript> // 資格情報エイリアスとサービス設定構造体を使用 dynamoConf = { "alias":"dynamoConf", "serviceName" : "DYNAMODB", "clientOverrideConfig":{ "retryPolicy":{ "numRetries":4 } }, "httpClientConfig":{ "maxConnections":50 } } dynamo = getCloudService("dynamoCred", dynamoConf) // アカウントのすべての DynamoDB テーブルをリストアップ listTablesStruct = { "Limit": 50 } listTablesResponse =dynamo.ListTables(listTablesStruct); writeDump(listTablesResponse) </cfscript>
設定エイリアスおよび資格情報の構造体
<cfscript> // 設定エイリアスとサービス資格情報構造体を使用 // DynamoDB 資格情報 dynamoCreds={ "vendorName":"AWS", alias": "dynamoCred", "region":"us-east-2", "accessKeyId": "access key", "secretAccessKey": "secret access" } dynamo = getCloudService(dynamoCreds, "dynamoConf") // アカウントのすべての DynamoDB テーブルをリストアップ listTablesStruct = { "Limit": 50 } listTablesResponse =dynamo.ListTables(listTablesStruct); writeDump(listTablesResponse) </cfscript>
資格情報と設定オプションの両方の構造体
<cfscript> // クラウドの資格情報と設定の構造体を使用 dynamoCred={ "vendorName":"AWS", "credentialAlias": "dynamoCred", "region":"us-east-2", "accessKeyId": "access key", "secretAccessKey": "secret access key" } dynamoConf = { "alias":"dynamoConf", "serviceName" : "DYNAMODB", "clientOverrideConfig":{ "retryPolicy":{ "numRetries":4 } }, "httpClientConfig":{ "maxConnections":50 } } dynamo = getCloudService(dynamoCred, dynamoConf) // アカウントのすべての DynamoDB テーブルをリストアップ listTablesStruct = { "Limit": 50 } listTablesResponse =dynamo.ListTables(listTablesStruct); writeDump(listTablesResponse) </cfscript>
Admin API
また、Admin API を使用することで、DynamoDB 資格情報および設定オプションを追加できます。資格情報および設定を追加するためのメソッドは、cloud.cfc で使用できます。
次に、メソッド addCredential(資格情報構造体)およびaddServiceConfig(設定構造体)
の使用例を示します。
資格情報の追加
<cfscript> // Administrator コンポーネントのオブジェクトを作成して login メソッドを呼び出す adminObj = createObject("component","cfide.adminapi.administrator") adminObj.login("admin") // クラウドコンポーネントのオブジェクトを作成 cloudObj = createObject("component","cfide.adminapi.cloud") // 資格情報構造体を定義 credentialStruct={ "alias" : "CredDynamo", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access key", "accessKeyId" : "access key" } // 資格情報の credentialStruct を追加 try{ cloudObj.addCredential(credentialStruct) writeOutput("Credentials added successfully") } catch(any e){ writeDump(e) } </cfscript>
設定の追加
<cfscript> // Administrator コンポーネントのオブジェクトを作成して login メソッドを呼び出す adminObj = createObject("component","cfide.adminapi.administrator") adminObj.login("admin") // クラウドコンポーネントのオブジェクトを作成 cloudObj = createObject("component","cfide.adminapi.cloud") // 設定構造体を定義 configStruct={ "alias":"ConfDynamo", "serviceName":"DYNAMODB", "clientOverrideConfig":{ "retryPolicy":{ "numRetries":4 } }, "httpClientConfig":{ "maxConnections":50 } } // 設定の configStruct を追加 try{ cloudObj.addServiceConfig(configStruct) writeOutput("Configuration service added successfully") } catch(any e){ writeDump(e) } </cfscript>
cfsetup
クラウド資格情報
追加
- add cloudcredential vendorName=AWS accessKeyId=SomeAccessKeyId secretAccessKey=SomeSecretKey region=us-west-1 alias=myAliasForCloudCredential
設定
- set cloudcredential myAliasForCloudCredential accessKeyId=newAccessKeyId
- set cloudcredential myAliasForCloudCredential secretAccessKey=newSecretAccessKey
- set cloudcredential myAliasForCloudCredential region=us-west-2
取得
- get cloudcredential myAliasForCloudCredential vendorName
- get cloudcredential myAliasForCloudCredential accessKeyId
- get cloudcredential myAliasForCloudCredential secretAccessKey
- get cloudcredential myAliasForCloudCredential region
- get cloudcredential myAliasForCloudCredential alias
表示
- show cloudcredential
- show cloudcredential myAliasForCloudCredential
削除
- delete cloudcredential myAliasForCloudCredential
クラウド設定
追加
- add cloudconfiguration serviceName=DYNAMODB alias=configAlias accelerateModeEnabled=true chunkedEncodingEnabled=true dualStackEnabled=true pathStyleAccessEnabled=true checksumValidationEnabled=true maxConnections=50 connectionMaxIdleTime=10s useIdleConnectionReaper=true socketTimeout=10s expectContinueEnabled=true connectionTimeout=10s connectionTimeToLive=10s connectionAcquisitionTimeout=10s useSystemPropertyValues=true numRetries=5 apiCallAttemptTimeout=2s
設定
- set cloudconfiguration configAlias maxconnections=40
- set cloudconfiguration configAlias maxconnections=40 numRetries=6
取得
- get cloudconfiguration configAlias serviceName
- get cloudconfiguration configAlias serviceName maxconnections
- get cloudconfiguration configAlias maxconnections
表示
- show cloudconfiguration
- show cloudconfiguration configAlias
削除
- delete cloudconfiguration configAlias
DynamoDB リクエストの実行
ColdFusion を使用して DynamoDB にリクエストを行うには、サービスハンドル getCloudService を使用して作成したオブジェクトである必要があります。
例として、DynamoDB のテーブルをスキャンします。ここでは、テーブルおよびその属性のすべての項目を表示します。レスポンスを表示するには、メソッド Scan に 2 つのパラメーターを指定する必要があります。次に示します。
- リクエストの本文
- カスタマイズオプション
リクエストパラメーター
すべてのリクエストパラメーターを含む構造体を作成します。DynamoDB テーブルをスキャンするには、これらのリクエストパラメーターを構造体として渡す必要があります。すべてのリクエストパラメーターのリストについては、Scan API を参照してください。
tableName="MusicTableForDemo" scanStruct = { "TableName": "#tableName#" }
カスタマイズオプション
2 番目のパラメーターには、ColdFusion が提供するいくつかのカスタマイズが含まれます。これは、レスポンスをカスタマイズします。
このパラメーターはオプションです。これらのカスタマイズが不要な場合は、空の構造体を渡すか、このパラメーターを空のままにします。
サポートされている最適化は次のとおりです。
- hasType:ブール値(デフォルト:false)
- customResponse:ブール値(デフォルト:false)
- binaryFormat:ブール値(デフォルト:false)
- preserveCFC:ブール値(デフォルト:false)
- cachedWithin:キャッシュに使用されます
- cachedAfter:キャッシュに使用されます
- cacheId:キャッシュに使用されます
- cacheRegion:キャッシュに使用されます
hasType
リクエストデータにタイプ(例:S、L、M など)が割り当てられているかどうかを指定します。値は true または false です。デフォルト値は false です。
true を指定した場合は、送信するすべてのデータ型のタイプを指定する必要があります。
false を指定した場合、データのタイプは自動的に決定されます。これは、Dynamo に送信する ColdFusion PDF/スプレッドシート/クエリ/CFC オブジェクトのデータを手動でシリアル化したくない場合に便利です。
<cfscript> dynamo=getCloudService(application.awsCred, application.dynamoConf) movieName="Movies010" // ステージ 1:テーブルを作成 tableStruct={ TableName : "#movieName#", KeySchema:[ { AttributeName: "year", KeyType: "HASH"}, { AttributeName: "title", KeyType: "RANGE"} ], AttributeDefinitions:[ { AttributeName: "year", AttributeType: "N" }, { AttributeName: "title", AttributeType: "S" } ], ProvisionedThroughput:{ ReadCapacityUnits: 10, WriteCapacityUnits: 10 } } dynamo.createTable(tableStruct) sleep(3000) // ステージ 2:テーブルに項目を挿入 putItemStruct={ "TableName":"#movieName#", "Item":{ "year": {"N": 2019}, "title": {"S": "Golden"} }, "ReturnValues": "NONE" } try{ putItemResponse=dynamo.putItem(putItemStruct,{"hasType": true}) writeOutput("Item inserted successfully in the table.") writeDump(putItemResponse) } catch (any e){ writeDump(e) } </cfscript>
customResponse
応答データにタイプ(例:S、L、M など)を付けるかどうかを指定します。値は true または false です。デフォルト値は false です。
true の場合、AWS からの応答では、結果の構造体にデータ型は含まれていません。これは、データを DynamoDB に書き込むときに、PDF/スプレッドシート/クエリ/CFC/画像オブジェクトを送信した場合に便利です。ColdFusion オブジェクト自体のデータを取得する場合は、customResponse オプションを true に指定する必要があります。
false の場合、応答マップには様々な AWS DynmaoDB データ型が表示されます。
<cfscript> // 資格情報と設定 dynamo = getCloudService(application.awsCred,application.dynamoConf) tableName="MusicTableForDemo" scanStruct = { "TableName": "#tableName#" } scanResponse=dynamo.scan(scanStruct,{"customResponse":true}) arr=scanResponse.items writeOutput("<b>List of songs</b>" & "") mapFunction=function(item){ writeOutput(item.SongTitle & "<br/>") } arr.map(mapFunction) </cfscript>
binaryFormat
binaryFormat 属性は、バイナリであるデータフィールドをカスタマイズします。値が true の場合、生のバイナリデータを返します。値が false の場合、DynamoDB によって返されるように、Base64 でエンコードされたデータを返します。customResponse: true の場合にのみ動作します。
次に例を示します。
<cfscript> // 資格情報と設定 dynamo = getCloudService(application.awsCred,application.dynamoConf) tableName="MusicTableForDemo" scanStruct = { "TableName": "#tableName#" } scanResponse=dynamo.scan(scanStruct,{"customResponse":true,"binaryFormat":true}) arr=scanResponse.items writeOutput("<b>List of songs</b>" & "") mapFunction=function(item){ writeOutput(item.SongTitle & "<br/>") } arr.map(mapFunction) </cfscript>
preserveCFC
DynamoDB オブジェクトに CFC を送信するかどうかを指定します。hasType: false の場合にのみ動作します。CFC の取得中に deserializeCFC オプションが機能するには、preserveCFC を true に設定する必要があります。
Employee.cfc
component accessors="true" { property string empName; property numeric age; property string dept; }
Helper.cfc
component accessors="true" { public function putItemCFC(dynamoObject, itemStruct, hasType, preserveCfc) { result = dynamoObject.putItem(itemStruct, {"hasType": hasType, "preserveCFC": preserveCfc}); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Items written successfully<br />"); } else { writeOutput("Failed to write the items<br />"); writeDump(result) } } }
SerializeCFC.cfm
<cfscript> empData = new Employee({empName="James", age=26, dept="000"}); region1 = "ap-northeast-2"; // 資格情報と設定 dynamo = getCloudService(application.awsCred,application.dynamoConf) tableName = "Table_Test_CFC"; TablePartitionKey = "OrderId"; partitionKeyType = "N"; TableSortKey = "OrderName"; sortKeyType = "S"; MyCFCKey = "OrderCFC"; LocalSecondaryIndexSortKey = "OrderDateTime"; secondaryIndexSortKeyType = "S"; myComponent = createObject("Component", "helper"); try { myComponent.deleteTable(dynamoUsWest1, tableName) } catch (any e) { writeDump(e) } try { myComponent.createTableWithLocalIndex(dynamoUsWest1, tableName, TablePartitionKey, partitionKeyType, TableSortKey, sortKeyType, LocalSecondaryIndexSortKey, secondaryIndexSortKeyType) sleep(20000); } catch (any e) { writeDump(e) } orderName = "MyOrder: "; strct_putItem = { "TableName": tableName, "Item":{ "#TablePartitionKey#": 2, "#TableSortKey#": "MyOrder: 2", "CUSTOMER_KEY": "0001-23456", "OrderStatus": "CONFIRMED", "Year": 2012, "#LocalSecondaryIndexSortKey#": "2020/04/21", "#MyCFCKey#": empData } } try { result = dynamoObject.putItem(itemStruct, {"hasType": false, "preserveCFC": true}); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Items written successfully<br />"); } else { writeOutput("Failed to write the items<br />"); writeDump(result) } } catch (any e) { writeDump(e) } </cfscript>
DynamoDB から CFC オブジェクトを取得する場合は、preserveCFC を true に設定します。動作するのは、customResponse: true の場合のみです。CFC オブジェクトが DynamoDB に格納されている場合は、preserveCFC を true に設定する必要があります。
cachedWithin
クエリをキャッシュする期間を指定します。この時間が経過すると、キャッシュ項目は使用できなくなります。自動的に破棄されます。
ColdFusion Administrator のサーバー設定/キャッシュに「Dynamo キャッシュを今すぐクリア」オプションが用意されています。このボタンをクリックすると、Dynamo キャッシュがクリアされます。
<cfscript> // 資格情報と設定 dynamo = getCloudService(application.awsCred,application.dynamoConf) posdateresult=DateAdd("s", 30, now()) tableName="MusicTableForDemo" scanStruct = { "TableName": "#tableName#" } scanResponse=dynamo.scan(scanStruct,{"customResponse":true, cachedWithin: "#createTimeSpan( 0, 0, 0, 30 )#"}) arr=scanResponse.items writeOutput("<b>List of songs</b>" & "") mapFunction=function(item){ writeOutput(item.SongTitle & "<br/>") } arr.map(mapFunction) </cfscript>
cachedAfter
クエリをキャッシュするまでの時間を指定します。キャッシュされたアイテムは、この時間が経過した後にのみ使用可能になります。
ColdFusion Administrator のサーバー設定/キャッシュに「Dynamo キャッシュを今すぐクリア」オプションが用意されています。このボタンをクリックすると、Dynamo キャッシュがクリアされます。
<cfscript> // 資格情報と設定 dynamo = getCloudService(application.awsCred,application.dynamoConf) posdateresult=DateAdd("s", 30, now()) tableName="MusicTableForDemo" scanStruct = { "TableName": "#tableName#" } scanResponse=dynamo.scan(scanStruct,{"customResponse":true,cachedAfter: posdateresult}) arr=scanResponse.items writeOutput("<b>List of songs</b>" & "") mapFunction=function(item){ writeOutput(item.SongTitle & "<br/>") } arr.map(mapFunction) </cfscript>
インラインサービス設定の場合は、クエリキャッシュが正常に機能するにはエイリアスキーが必須です。
例
config = {
"alias": "myConfig",
"serviceName" : "DYNAMODB"
};
管理者ポータルの場合、エイリアスは既に必須になっています。
名前付きパラメーター
ColdFusion DyanamoDB API では、属性の名前付きパラメーターもサポートしています。
次のパラメーターです。
- query
- options
query パラメーターには、送信する必要があるペイロードが含まれています。
例えば、テーブルのスキャンの場合、query={TableName: “yourTable”} のように指定できます。
options パラメーターは、DynamoDB でサポートされているすべてのオプションを指定する構造体です。
例えば、hasType や customResponse などです。
Options={hasType: true}
<cfscript> dynamo=getCloudService(application.awsCred, application.dynamoConf) movieName="Movies010" // ステージ 1:テーブルを作成 tableStruct={ TableName : "#movieName#", KeySchema:[ { AttributeName: "year", KeyType: "HASH"}, { AttributeName: "title", KeyType: "RANGE"} ], AttributeDefinitions:[ { AttributeName: "year", AttributeType: "N" }, { AttributeName: "title", AttributeType: "S" } ], ProvisionedThroughput:{ ReadCapacityUnits: 10, WriteCapacityUnits: 10 } } dynamo.createTable(tableStruct) sleep(3000) // ステージ 2:テーブルに項目を挿入 putItemStruct={ "TableName":"#movieName#", "Item":{ "year": {"N": 2019}, "title": {"S": "Golden"} }, "ReturnValues": "NONE" } try{ putItemResponse=dynamo.putItem(query = putItemStruct, options = {"hasType": true}) writeOutput("Item inserted successfully in the table.")writeDump(putItemResponse) } catch (any e){ writeDump(e) } </cfscript>
大文字と小文字を区別する構造体
ColdFusion の構造体が大文字と小文字を区別しないのに対して、DynamoDB は大文字と小文字を区別します。この問題に対処するために、新しい struct 型、casesensitive が導入されました。これは、大文字小文字を保持します。ColdFusion で次を使用して、リクエストを DynamoDB に渡すことができます。
- Struct または
- CaseSensitiveStruct
DynamoDB メソッドを扱う場合は、大文字と小文字を区別する構造体を使用することをお勧めします。DynamoDB は大文字と小文字を区別するので、これを行うことで、大文字と小文字を区別しないことによるデータ損失を避けることができます。
次に例を示します。
cfscript> cred = { "credentialAlias" : "MyCredential", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; "accessKeyId" : "XXXXXXXXXXXXXXXXX" } config = { "serviceName" = "DYNAMODB" }; dynamo = getCloudService(cred, config); strct = structNew("casesensitive"); strct.TableName = "College" writedump(strct); result = dynamo.scan(strct, {} ); writedump(result); </cfscript>
高度なデータ型のサポート
次のデータ型がサポートされています。
- CFC:オプション preserveCFC を true に設定して使用します。
- Date
- BigDecimal
- PDF:バイナリ応答オブジェクトで任意の cfpdf メソッドを使用します。
- Query:AWS 応答オブジェクトで QueryNew メソッドを使用します。
- Image
- Spreadsheet:SpreadSheetRead メソッドを使用し、応答オブジェクトをバイナリ形式で渡します。
- XML:AWS 応答オブジェクトで DeserializeXML メソッドを使用します。
次の例は、ColdFusion を使用してスプレッドシートオブジェクトを DynamoDB に格納および DynamoDB から取得する方法を示しています。
スプレッドシート
helperFuctions.cfc
component { function getLocalSecondaryIndex(partitionKey, sortKey, tableName) { localSecondaryIndex = [{ "IndexName": "LocalIndex_" & tableName, "KeySchema": [ { "AttributeName": partitionKey, "KeyType": "HASH" }, { "AttributeName": sortKey, "KeyType": "RANGE" } ], "Projection": { "ProjectionType": "KEYS_ONLY" } }] return localSecondaryIndex; } function getGlobalSecondaryIndex(partitionKey, sortKey, tableName) { globalSecondaryIndex = [{ "IndexName": "GlobalIndex_" & tableName, "KeySchema": [ { "AttributeName": partitionKey, "KeyType": "HASH" }, { "AttributeName": sortKey, "KeyType": "RANGE" } ], "Projection": { "ProjectionType": "KEYS_ONLY" }, "ProvisionedThroughput": { "ReadCapacityUnits": 10, "WriteCapacityUnits": 10 } }] return globalSecondaryIndex; } function getCreateTableStruct(tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType) { createTable = { "TableName": tableName, "KeySchema": [ { "AttributeName": partitionKeyName, "KeyType": "HASH" }, { "AttributeName": sortKeyName, "KeyType": "RANGE" } ], "AttributeDefinitions": [ { "AttributeName": partitionKeyName, "AttributeType": partitionKeyType }, { "AttributeName": sortKeyName, "AttributeType": sortKeyType } ], "ProvisionedThroughput": { "ReadCapacityUnits": 10, "WriteCapacityUnits": 10 }, "StreamSpecification": { "StreamEnabled": true, "StreamViewType": "NEW_AND_OLD_IMAGES" } } return createTable; } public function createTable(dynamoObject, tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType) { createTable = getCreateTableStruct(tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType); try { result = dynamoObject.createTable(createTable); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Creating the table<br />"); } else { writeOutput("Failed to create the table<br />"); } } catch (any e) { writeDump(e) } } public function createTableWithLocalIndex(dynamoObject, tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType, localSortKey, localSortKeyType) { createTable = getCreateTableStruct(tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType); localIndex = getLocalSecondaryIndex(partitionKeyName, localSortKey, tableName) structInsert(createTable, "LocalSecondaryIndexes", localIndex); attributeDefinitionArray = structFind(createTable, "AttributeDefinitions") myStruct = structNew(); myStruct["AttributeName"] = localSortKey; myStruct["AttributeType"] = localSortKeyType; arrayAppend(attributeDefinitionArray, myStruct) structUpdate(createTable, "AttributeDefinitions", attributeDefinitionArray); try { result = dynamoObject.createTable(createTable); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Creating the table<br />"); } else { writeOutput("Failed to create the table<br />"); } } catch (any e) { writeDump(e) } } public function createTableWithGlobalIndex(dynamoObject, tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType, globalPartitionKey, globalPartitionKeyType, globalSortKey, globalSortKeyType) { createTable = getCreateTableStruct(tableName, partitionKeyName, partitionKeyType, sortKeyName, sortKeyType); globalIndex = getGlobalSecondaryIndex(globalPartitionKey, globalSortKey, tableName) structInsert(createTable, "GlobalSecondaryIndexes", globalIndex); attributeDefinitionArray = structFind(createTable, "AttributeDefinitions") myStruct = structNew(); myStruct["AttributeName"] = globalPartitionKey; myStruct["AttributeType"] = globalPartitionKeyType; arrayAppend(attributeDefinitionArray, myStruct) myStruct1 = structNew(); myStruct1["AttributeName"] = globalSortKey; myStruct1["AttributeType"] = globalSortKeyType; arrayAppend(attributeDefinitionArray, myStruct1) structUpdate(createTable, "AttributeDefinitions", attributeDefinitionArray); try { result = dynamoObject.createTable(createTable); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Creating the table<br />"); } else { writeOutput("Failed to create the table<br />"); } } catch (any e) { writeDump(e) } } public function deleteTable(dynamoObject, tableName) { deleteTable = { TableName: tableName } try { result = dynamoObject.deleteTable(deleteTable); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Deleting the table<br />"); } } catch (any e) { if(e.ExceptionDetails.ExceptionCode eq "ResourceNotFoundException") { writeOutput("Deleting the table<br />"); } else { writeOutput("Failed to delete the table<br />"); writeDump(e) } } } public function createGlobalTable(dynamoObject, tableName, replicaRegion1, replicaRegion2) { createGlobalTable = { "GlobalTableName": tableName, "ReplicationGroup": [ { "RegionName": replicaRegion1 }, { "RegionName": replicaRegion2 } ] } public function putItem(dynamoObject, itemStruct, hasType) { result = dynamoObject.putItem(itemStruct, {"hasType": hasType}); if(result.HttpResponse.StatusCode eq 200) { writeOutput("Items written successfully<br />"); } else { writeOutput("Failed to write the items<br />"); writeDump(result) } } }
sp.cfm
<cfscript> region1 = "us-west-1"; cred_west1 = { "alias" : "alias", "vendorName" : "AWS", "region" : region1, "secretAccessKey" : "secret access key", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" }; dynamoUsWest1 = getCloudService(cred_west1, config); tableName = "Table_Cache_GetItem_1"; TablePartitionKey = "OrderId"; partitionKeyType = "N"; TableSortKey = "OrderName"; sortKeyType = "S"; LocalSecondaryIndexSortKey = "OrderDateTime"; secondaryIndexSortKeyType = "S"; myComponent = createObject("Component", "helperFunctions"); try { myComponent.deleteTable(dynamoUsWest1, tableName) } catch (any e) { writeDump(e) } try { myComponent.createTableWithLocalIndex(dynamoUsWest1, tableName, TablePartitionKey, partitionKeyType, TableSortKey, sortKeyType, LocalSecondaryIndexSortKey, secondaryIndexSortKeyType) sleep(20000); } catch (any e) { writeDump(e) } orderName = "MyOrder: "; strct_putItem = { "TableName": tableName, "Item":{ "#TablePartitionKey#": 2, "#TableSortKey#": "MyOrder: ", "CUSTOMER_KEY": "0001-23456", "OrderStatus": "CONFIRMED", "Year": 2012, "#LocalSecondaryIndexSortKey#": "2020/04/21" } } for(i = 1; i < 5; i++) { structUpdate(strct_putItem.Item, "#TablePartitionKey#", i); structUpdate(strct_putItem.Item, "#TableSortKey#", orderName & i); myComponent.putItem(dynamoUsWest1, strct_putItem, "false") sleep(10000) } strct_getItem = { "TableName": tableName, "Key": { "#TablePartitionKey#": 2, "#TableSortKey#": "MyOrder: 2" }, "ExpressionAttributeNames": { "##Yr": "Year" }, "ProjectionExpression": "#TablePartitionKey#, ##Yr, OrderStatus", "ConsistentRead": false, "ReturnConsumedCapacity": "INDEXES" } try { result = dynamoUsWest1.getItem(strct_getItem, {CustomResponse: true, cachedWithin: "#createTimeSpan( 0, 0, 0, 45 )#"}); if( (result.ConsumedCapacity.CapacityUnits == 0.5) && (!structKeyExists(result.Item, "CUSTOMER_KEY")) && (result.Item.OrderId == 2) && (result.Item.Year == 2012) && (structKeyExists(result.ConsumedCapacity, "Table")) ) { writeOutput("SUCCESS<br />"); } else { writeOutput("FAIL<br />"); } } catch (any e) { writeDump(e); } strct_putItem = { "TableName": tableName, "Item":{ "#TablePartitionKey#": 2, "#TableSortKey#": "MyOrder: 2", "CUSTOMER_KEY": "0001-23456", "OrderStatus": "CONFIRMED", "Year": 2020, "#LocalSecondaryIndexSortKey#": "2020/04/21" } } myComponent.putItem(dynamoUsWest1, strct_putItem, "false") sleep(10000) try { result = dynamoUsWest1.getItem(strct_getItem, {CustomResponse: true, cachedWithin: "#createTimeSpan( 0, 0, 0, 45 )#"}); if( (result.ConsumedCapacity.CapacityUnits == 0.5) && (!structKeyExists(result.Item, "CUSTOMER_KEY")) && (result.Item.OrderId == 2) && (result.Item.Year == 2012) && (structKeyExists(result.ConsumedCapacity, "Table")) ) { writeOutput("SUCCESS<br />"); } else { writeOutput("FAIL<br />"); } } catch (any e) { writeDump(e); } sleep(36000) try { result = dynamoUsWest1.getItem(strct_getItem, {CustomResponse: true, cachedWithin: "#createTimeSpan( 0, 0, 0, 45 )#"}); if( (result.ConsumedCapacity.CapacityUnits == 0.5) && (!structKeyExists(result.Item, "CUSTOMER_KEY")) && (result.Item.OrderId == 2) && (result.Item.Year == 2020) && (structKeyExists(result.ConsumedCapacity, "Table")) ) { writeOutput("SUCCESS<br />"); } else { writeOutput("FAIL<br />"); } } catch (any e) { writeDump(e); } try { myComponent.deleteTable(dynamoUsWest1, tableName) } catch (any e) { writeDump(e) } </cfscript>
DynamoDB 関数
テーブル関数
すべての SQL および NoSQL データベースのように、Amazon DynamoDB はテーブルにデータを格納します。次に、DynamoDB テーブルで実行できる操作の一部を示します。
テーブルの作成
テーブルを作成するには、関数 createTable を使用します。テーブルを作成するには、次を指定する必要があります。
- テーブルの名前
- プライマリキー:プライマリキーは、1 つの属性(パーティションキー)または 2 つの属性(パーティションキーと並べ替えキー)で構成されます。属性名、データ型および各属性のロール(HASH(パーティションキー用)および RANGE(並べ替えキー用))を指定する必要があります。
- スループット設定:テーブルの初期読み取りおよび書き込みスループット設定を指定します。
次の例では、テーブル MusicForMe を作成します。プライマリキーは、Artist(パーティションキー)およびSongTitle(並べ替えキー)で構成されます(両方のキーは String のデータ型を持ちます)。このテーブルの最大スループットは、10 ユニットの読み取りキャパシティおよび 5 ユニットの書き込みキャパシティです。
<cfscript> cred = { "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" } dynamo = getCloudService(cred, config) createTableStruct={ TableName:"MusicForMe", AttributeDefinitions:[ {AttributeName:"Artist",AttributeType:"S"}, {AttributeName:"SongTitle",AttributeType:"S"} ], KeySchema:[ {AttributeName:"Artist",KeyType:"HASH"}, {AttributeName:"SongTitle",KeyType:"RANGE"} ], ProvisionedThroughput:{ ReadCapacityUnits: 10, WriteCapacityUnits: 10 } } try{ createTableResponse=dynamo.createTable(createTableStruct,{"customResponse": true}) writeOutput("Table created successfully") writeDump(createTableResponse) } catch(any e){ writeDump(e) } </cfscript>
テーブルの説明
テーブルを作成したら、次のようなテーブル情報を表示できます。
- 属性
- 作成日
- グローバルセカンダリインデックス
- ローカルセカンダリインデックス
- スキーマ
- プロビジョニング済みのスループット
テーブルの情報の表示には、関数 describeTable を使用します。
次に、前の節で作成したテーブル MusicForMe の例を説明します。
<cfscript> cred = { "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" } dynamo = getCloudService(cred, config) // テーブル「MusicForMe」に関する情報を取得 if (ArrayContains(listTablesResponse.TableNames,"MusicForMe")){ describeTableStruct={ "TableName":"YearlyProductCatalog" } describeTableResponse=dynamo.describeTable(describeTableStruct) writeDump(describeTableResponse) } else{ writeOutput("Table not found") } </cfscript>
テーブルの更新
DynamoDB テーブルの更新には、テーブルのプロビジョニング済みの設定、読み取り/書き込みキャパシティモード、テーブルのグローバルセカンダリインデックスのいずれかの変更を伴います。
詳しくは、updateTable を参照してください。
次の例では、テーブル MusicForMe の読み取りおよび書き込みキャパシティユニットの値を更新します。
<cfscript> cred = { "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" } dynamo = getCloudService(cred, config) tableName="MusicForMe" oldReadCapacityUnits=10 oldWriteCapacityUnits=10 newReadCapacityUnits=50 newWriteCapacityUnits=50 updateTableStruct={ "TableName": "#tableName#", "ProvisionedThroughput": { "ReadCapacityUnits": "#newReadCapacityUnits#", "WriteCapacityUnits": "#newWriteCapacityUnits#" } } try{ updateTableResponse=dynamo.updateTable(updateTableStruct) if( (updateTableResponse.HttpResponse.StatusCode==200) and (updateTableResponse.TableDescription.ProvisionedThroughput.ReadCapacityUnits==oldReadCapacityUnits) and (updateTableResponse.TableDescription.ProvisionedThroughput.WriteCapacityUnits==oldWriteCapacityUnits) and (updateTableResponse.TableDescription.TableStatus=="UPDATING") ) { writeOutput("Old read and write values correct.") } else { writeOutput("Old read and write values incorrect.") } } catch(any e) { writeDump(e) } </cfscript>
テーブルの削除
deleteTable 関数を使用することで、以前に作成したテーブルを削除します。テーブルを削除したら、復元できません。
次の例では、テーブル MusicForMe を削除します。
<cfscript> cred = { "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" } dynamo = getCloudService(cred, config) tableName="MusicForMe" // テーブルを削除 deleteTableStruct={ "TableName": "#tableName#" } try{ deleteResponse=dynamo.deleteTable(deleteTableStruct) writeOutput("Table deleted successfully") writeDump(deleteResponse) } catch (any e){ writeOutput("Unable to delete the table") writeDump(e) } </cfscript>
すべてのテーブルのリスト表示
AWS リージョンおよびアカウントのすべてのテーブルを確認するには、関数 listTables を使用します。
この関数は、アカウントのすべてのテーブルの配列を返します。
次の例では、アカウントに存在するテーブルの名前を返します(最大で 50)。適宜、制限を変更できます。
<cfscript> cred={ "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } conf={ "serviceName"="DYNAMODB" } dynamo=getCloudService(cred, conf) params = { "Limit": 50 } result = dynamo.ListTables(params); writeDump(result) </cfscript>
テーブルへのデータの書き込み
項目の挿入
テーブルに項目を挿入します。関数 putItem を使用して、新しい項目を挿入します。同じキーを持つ項目がテーブルに既に存在している場合は、新しい項目で置き換えられます。
次の例では、テーブル NewProductCatalog を作成して、テーブルに項目を挿入します。
<cfscript> cred={ "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } conf={ "serviceName"="DYNAMODB" } dynamo=getCloudService(cred, conf) tableName="NewProductCatalog" // ステージ 1:テーブルを作成 createTableStruct={ "TableName": "#tableName#", "KeySchema": [ { "AttributeName": "id", "KeyType": "HASH" } ], "AttributeDefinitions": [ { "AttributeName": "id", "AttributeType": "N" } ], "ProvisionedThroughput": { "ReadCapacityUnits": 10, "WriteCapacityUnits": 10 } } dynamo.createTable(createTableStruct) sleep(20000) // ステージ 2:項目を挿入 putItemStruct = { "TableName": "#tableName#", "Item":{ "id": { "N": 250 }, "Title": { "S": "Hamlet" }, "Price": { "N": "20" } }, "ReturnValues": "ALL_OLD" } try{ putItemResponse=dynamo.putItem(putItemStruct,{"hasType": true}) writeOutput("Item inserted successfully") writeDump(putItemResponse) } catch (any e){ writeDump(e) } </cfscript>
項目の更新
項目を挿入したら、updateItem 関数を使用することで、項目を更新できます。
指定されたキーを含む項目が存在しない場合、この関数は項目を作成します。存在する場合は、既存の項目の属性を変更します。
<cfscript> cred={ "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } conf={ "serviceName"="DYNAMODB" } dynamo=getCloudService(cred, conf) tableName="NewProductCatalog" // 挿入された項目を更新 updateItemStruct={ "TableName": "#tableName#", "Key": { "id": { "N": 250 } }, "UpdateExpression": "set Title = :val1", "ConditionExpression": "Price = :val2", "ExpressionAttributeValues": { ":val1": {"S": "Macbeth"}, ":val2": {"N": "200"} }, "ReturnValues": "ALL_NEW" } try{ result = dynamo.updateItem(updateItemStruct, {"hasType": true}) if(result.Attributes.Title.S == "Hamlet") { writeOutput("Title changed successfully<br/>") } else { writeOutput("Failed to change the title<br/>") } } catch (any e){ writeDump(e) } </cfscript>
項目の削除
deleteItem 関数を使用することで、テーブルの項目を削除します。
<cfscript> cred = { "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } config = { "serviceName" = "DYNAMODB" } dynamo = getCloudService(cred, config) tableName="YearlyProductCatalog" // 削除する項目 id=550 title="hamlet" // テーブル内の該当する項目を削除 deleteItemStruct={ "TableName":"#tableName#", "Key":{ "id":{"N":"#id#"}, "title":{"S":"#title#"} }, "ReturnValues": "ALL_OLD" } try{ deleteItemResponse=dynamo.deleteItem(deleteItemStruct,{"hasType": true}) writeOutput("Item deleted successfully") writeDump(deleteItemResponse) } catch(any e){ writeDump(e) } </cfscript>
テーブルからの項目の読み取り
DynamoDB テーブルから項目を読み取るには、関数 getItem を使用します。テーブルの名前を、目的の項目のプライマリキーと共に指定する必要があります。
<cfscript> cred={ "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } conf={ "serviceName"="DYNAMODB" } dynamo=getCloudService(cred, conf) // テーブルを作成 tableName="MusicForAll" createTableStruct={ TableName:"#tableName#", AttributeDefinitions:[ {AttributeName:"Artist",AttributeType:"S"}, {AttributeName:"SongTitle",AttributeType:"S"} ], KeySchema:[ {AttributeName:"Artist",KeyType:"HASH"}, {AttributeName:"SongTitle",KeyType:"RANGE"} ], ProvisionedThroughput:{ ReadCapacityUnits: 10, WriteCapacityUnits: 10 } } try{ createTableResponse=dynamo.createTable(createTableStruct,{"customResponse": true}) writeOutput("Table created successfully") writeDump(createTableResponse) } catch(any e){ writeDump(e) } // テーブルに項目を挿入 putItemStruct = { "TableName": "#tableName#", "Item":{ "Artist":{"S":"Beatles"}, "SongTitle":{"S":"Yesterday"}, "Album":{"S":"Some album"} }, "ReturnValues":"NONE" } try{ putItemResponse=dynamo.putItem(putItemStruct,{"hasType": true}) writeOutput("Item inserted successfully in the table.")writeDump(putItemResponse) } catch (any e){ writeDump(e) } // 挿入された項目を取得 getItemStruct={ "TableName": "#tableName#", "Key":{ "Artist":{"S":"Beatles"} } } try{ getItemResponse=dynamo.putItem(getItemStruct) writeOutput("Item retrieved successfully in the table.")writeDump(putItemResponse) } catch (any e){ writeDump(e) } </cfscript>
テーブルの項目の更新
前の節で項目を挿入したら、その項目を更新できます。次の例では、Album を新しい値に更新しています。
<cfscript> cred={ "credentialAlias" : "alias", "vendorName" : "AWS", "region" : "us-east-2", "secretAccessKey" : "secret access", "accessKeyId" : "access key" } conf={ "serviceName"="DYNAMODB" } dynamo=getCloudService(cred, conf) tableName="MusicForAll" // テーブル内の該当する項目を更新 updateItemStruct={ "TableName":"#tableName#", "Key":{ "Artist":{"S":"Beatles"}, "SongTitle":{"S":"Yesterday"} }, "UpdateExpression": "SET Album = :newval", "ExpressionAttributeValues":{ ":newval": {"S": "Some other title"} }, "ReturnValues": "ALL_NEW" } try{ updateItemResponse=dynamo.updateItem(updateItemStruct,{"hasType":true,"customResponse":true}) writeDump(updateItemResponse) } catch(any e){ writeDump(e) } </cfscript>