ããã¯ããªã«ãããããŠæžãããã®ïŒ
Amazon DynamoDBã¯äœ¿ã£ãããšããªãã®ã§ãããããŒã«ã«ã§åãããããŒãžã§ã³ããããããªã®ã§ã詊ããŠãããããªãšããããšã§ã
Amazon DynamoDB とは - Amazon DynamoDB
Amazon DynamoDB
ãããããAmazon DynamoDBãç¥ããªãã®ã§ããŸãã¯è»œãããã¥ã¡ã³ããçºããŠã¿ãŸãã
Amazon DynamoDB とは - Amazon DynamoDB
ç¹åŸŽã¯ããã¡ãã®é äžã®ããŒãžãèŠãã®ãè¯ãããã§ãã
Amazon DynamoDB: 仕組み - Amazon DynamoDB
ãã£ãšèŠããšããããªãšããã§ããããã
- åºæ¬çãªã³ã³ããŒãã³ããšããŠãããŒãã«ãã¢ã€ãã ã屿§ããã
- ã¢ã€ãã ã¯ããããã¬ã³ãŒãã屿§ã¯ã«ã©ã ããã£ãŒã«ãã«çžåœ
- ããŒãã«ã¯ãªãŒãžã§ã³å ã§äžæã§ããå¿ èŠããã
- 屿§ã¯ãã¹ããå¯èœ
- ãã©ã€ããªãŒããŒã¯ãããŒãã£ã·ã§ã³ããŒãããŒãã£ã·ã§ã³ããŒïŒãœãŒãããŒïŒè€åãã©ã€ããªãŒããŒïŒã®2çš®é¡ããéžæå¯èœ
- ããŒã¿ã¯ãããŒãã£ã·ã§ã³ããŒã«ãã忣é 眮ããã
- ãã©ã€ããªãŒããŒä»¥å€ã¯ãã¹ããŒãã¬ã¹ã§ãã
- ããŒãã«ã«ã»ã«ã³ããªã€ã³ããã¯ã¹ãå®çŸ©ã§ãã
- PartiQLãšããã¯ãšãªèšèªã䜿ãããCRUD APIã䜿ã£ãŠããŒã¿ã«ã¢ã¯ã»ã¹ã§ãã
- ãã©ã³ã¶ã¯ã·ã§ã³ãå©çšã§ãã
- ããŒã¿åã«ã¯ã¹ã«ã©ãŒïŒæ°å€ãæååããã€ããªãããŒã«ãnullïŒãšããã¥ã¡ã³ãïŒListãMapãSetsïŒããã
- AZéã§ã¬ããªã±ãŒã·ã§ã³ãããŠãããèªã¿èŸŒã¿æã®æŽåæ§ã調æŽå¯èœ
- èªã¿æžãã®ã¹ã«ãŒãããã調æŽå¯èœ
- DynamoDB StreamsãšãããããŒã¿å€æŽã€ãã³ããåãåãä»çµã¿ããã
Amazon DynamoDBãšRDBMSã®éãã¯ããã¡ãã®ããã¥ã¡ã³ããåç §ã
SQL から NoSQL へ - Amazon DynamoDB
ããŒã«ã«çã®Amazon DynamoDB
Amazon DynamoDBã®ããŒã«ã«çã¯ãJava 6以äžãåäœèŠä»¶ã®ããã§ãã
DynamoDB ローカル (ダウンロード可能バージョン) のセットアップ - Amazon DynamoDB
ããŒã«ã«çã®Amazon DynamoDBã«é¢ããæ³šæäºé ã¯ããã¡ãã
DynamoDB Local の使用に関する注意事項 - Amazon DynamoDB
ããŒã¿ã®ä¿åå
ã¯ãã¡ã€ã«ïŒåäžãŸãã¯AWSã¢ã¯ã»ã¹ããŒIDãšãªãŒãžã§ã³ã®çµã¿åããïŒãã¡ã¢ãªã«ãªãããã§ãã
ãŸããå®éã«AWSã§åäœããããŒãžã§ã³ãšããã€ãéããããããã§ãã
ããã¥ã¡ã³ããèŠãã®ã¯ãããªãšããã«ããŠããšãããã䜿ã£ãŠã¿ãŸãããã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã
$ java --version openjdk 17.0.1 2021-10-19 OpenJDK Runtime Environment (build 17.0.1+12-Ubuntu-120.04) OpenJDK 64-Bit Server VM (build 17.0.1+12-Ubuntu-120.04, mixed mode, sharing) $ aws --version aws-cli/2.4.14 Python/3.8.8 Linux/5.4.0-96-generic exe/x86_64.ubuntu.20 prompt/off
åäœç¢ºèªã¯ãããã°ã©ã ããã®ã¢ã¯ã»ã¹ã§è¡ãããšã«ããŸããNode.jsã䜿ãããšã«ããŸããã
$ node --version v16.13.2
ããŒã«ã«çAmazon DynamoDBãã€ã³ã¹ããŒã«ãã
ããŒã«ã«çã®Amazon DynamoDBã¯ããã¡ãã®ããã¥ã¡ã³ãã«æ²¿ã£ãŠååŸã§ããŸãã
コンピュータ上で DynamoDB をローカルでデプロイする - Amazon DynamoDB
ããŒã«ã«ã«ãã¡ã€ã«ãããŠã³ããŒãããæ¹æ³ãDockerã€ã¡ãŒãžãäœ¿ãæ¹æ³ãMavenã¢ãŒãã£ãã¡ã¯ããšããŠååŸããæ¹æ³ã®3ã€ãããããã§ããã
ä»åã¯çŽ çŽã«ããŠã³ããŒãããŠã¿ãŸãã
$ curl -OL https://s3.ap-northeast-1.amazonaws.com/dynamodb-local-tokyo/dynamodb_local_latest.tar.gz
å±éã
$ tar xf dynamodb_local_latest.tar.gz
ãããªæãã«å±éãããŸãã
$ ll åèš 48736 drwxrwxr-x 3 xxxxx xxxxx 4096 1æ 28 01:46 ./ drwxrwxr-x 7 xxxxx xxxxx 4096 1æ 28 01:45 ../ -rw-r--r-- 1 xxxxx xxxxx 5863882 1æ 11 03:08 DynamoDBLocal.jar drwxr-xr-x 2 xxxxx xxxxx 4096 1æ 28 01:46 DynamoDBLocal_lib/ -rw-r--r-- 1 xxxxx xxxxx 9450 1æ 11 03:06 LICENSE.txt -rw-r--r-- 1 xxxxx xxxxx 4873 1æ 11 03:06 README.txt -rw-r--r-- 1 xxxxx xxxxx 29753 1æ 11 03:06 THIRD-PARTY-LICENSES.txt -rw-rw-r-- 1 xxxxx xxxxx 43970290 1æ 28 01:46 dynamodb_local_latest.tar.gz
DynamoDBLocal_lib
ãšãããã£ã¬ã¯ããªã«ã¯ãããŒã«ã«çã®Amazon DynamoDBãäŸåãããšæãããJARãã¡ã€ã«ã.so
ãã¡ã€ã«ã
.dll
ãã¡ã€ã«ãå«ãŸããŠããŸãã
èµ·åã¯ã以äžã®ã³ãã³ãã§è¡ããŸãã
$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar [ãªãã·ã§ã³]
ãã«ãã
$ java -jar DynamoDBLocal.jar -help usage: java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar [-port <port-no.>] [-inMemory] [-delayTransientStatuses] [-dbPath <path>][-sharedDb] [-cors <allow-list>] -cors <arg> Enable CORS support for javascript against a specific allow-list list the domains separated by , use '*' for public access (default is '*') -dbPath <path> Specify the location of your database file. Default is the current directory. -delayTransientStatuses When specified, DynamoDB Local will introduce delays to hold various transient table and index statuses so that it simulates actual service more closely. Currently works only for CREATING and DELETING online index statuses. -help Display DynamoDB Local usage and options. -inMemory When specified, DynamoDB Local will run in memory. -optimizeDbBeforeStartup Optimize the underlying backing store database tables before starting up the server -port <port-no.> Specify a port number. Default is 8000 -sharedDb When specified, DynamoDB Local will use a single database instead of separate databases for each credential and region. As a result, all clients will interact with the same set of tables, regardless of their region and credential configuration. (Useful for interacting with Local through the JS Shell in addition to other SDKs)
ããŒãžã§ã³ãããããªãã®ã§ããã忢±ãããŠããREADME.md
ã«æžãããŠãããã®ã確èªããã°ããã®ã§ããããã
$ grep -A 2 'Release Notes' README.txt Release Notes ----------------------------- 2022-1-10 (1.18.0)
ããŒã¿ã®ä¿åå ã¯ã以äžã®3ãã¿ãŒã³ããããŸãã
-sharedDb
ãªãã·ã§ã³ãä»äžããŠèµ·åãã âŠshared-local-instance.db
ãšããåäžã®ãã¡ã€ã«ã«å šã¯ã©ã€ã¢ã³ãã®ããŒã¿ãä¿åãã-sharedDb
ãªãã·ã§ã³ãä»äžããªã âŠ[AWSã¢ã¯ã»ã¹ããŒID]_[ãªãŒãžã§ã³å].db
ãšãããã¡ã€ã«ã«ãAWSã¢ã¯ã»ã¹ããŒIDããã³ãªãŒãžã§ã³åäœã«ããŒã¿ãä¿åããã-inMemory
ãªãã·ã§ã³ãä»äžãã ⊠ããŒã¿ã¯ãã€ã³ã¡ã¢ãªãŒã«ä¿åããã
ããŒã¿ãã€ã³ã¡ã¢ãªãŒã«ä¿æããå Žåã¯ããŒã«ã«çã®Amazon DynamoDBãåèµ·åãããšããŒã¿ããªããªããŸããããã¡ã€ã«ã«ä¿åããŠããå Žåã¯
åœç¶ã§ãããã¡ã€ã«ãåé€ãããšããŒã¿ããªããªããŸãã
ä»åã¯ã€ã³ã¡ã¢ãªãŒã§èµ·åããŠã¿ãŸãã
$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -inMemory
ããŒã8000
ã§ãªãã¹ã³ããããã§ããã
Port: 8000 InMemory: true DbPath: null SharedDb: false shouldDelayTransientStatuses: false CorsParams: *
AWS CLIã§ã¢ã¯ã»ã¹ãã
ããŒã«ã«çã®Amazon DynamoDBãèµ·åããã®ã§ãAWS CLIã§ã¢ã¯ã»ã¹ããŠã¿ãŸãããã
ããã¥ã¡ã³ããèŠããšãã¯ã¬ãã³ã·ã£ã«ã¯èšå®ããå¿ èŠããããããªã®ã§
コンピュータ上で DynamoDB をローカルでデプロイする - Amazon DynamoDB
ç°å¢å€æ°ã§èšå®ã
$ export AWS_ACCESS_KEY_ID=fakeMyKeyId $ export AWS_SECRET_ACCESS_KEY=fakeSecretAccessKey $ export AWS_DEFAULT_REGION=ap-northeast-1
--endpoint-url
ãããŒã«ã«çã®Amazon DynamoDBã«æå®ãããšãã¢ã¯ã»ã¹ã§ããŸãã
$ aws dynamodb list-tables --endpoint-url http://localhost:8000 { "TableNames": [] }
ç¶ããŠãããŒãã«ãäœæããŠã¿ãŸãããã
ステップ 1: テーブルを作成する - Amazon DynamoDB
ããã¥ã¡ã³ãã«æ²¿ã£ãŠã--endpoint-url
ãæå®ãã€ã€ããŒãã«ãäœæã
$ aws dynamodb create-table \ --endpoint-url http://localhost:8000 \ --table-name Music \ --attribute-definitions \ AttributeName=Artist,AttributeType=S \ AttributeName=SongTitle,AttributeType=S \ --key-schema \ AttributeName=Artist,KeyType=HASH \ AttributeName=SongTitle,KeyType=RANGE \ --provisioned-throughput \ ReadCapacityUnits=10,WriteCapacityUnits=5 \ --table-class STANDARD
åãã©ã¡ãŒã¿ãŒã®æå³ã¯ãAPIãªãã¡ã¬ã³ã¹ãã確èªã§ããŸãã
ããŒãã«ã®äœæã確èªã
$ aws dynamodb describe-table --endpoint-url http://localhost:8000 --table-name Music | grep TableStatus "TableStatus": "ACTIVE",
ã§ãããã®å®çŸ©ã®æå³ãããããªããŸãŸé²ãã§ãæå³ããªãæ°ãããã®ã§ã確èªããŠãããŸãããã
--table-name Music \ --attribute-definitions \ AttributeName=Artist,AttributeType=S \ AttributeName=SongTitle,AttributeType=S \ --key-schema \ AttributeName=Artist,KeyType=HASH \ AttributeName=SongTitle,KeyType=RANGE \ --provisioned-throughput \ ReadCapacityUnits=10,WriteCapacityUnits=5 \ --table-class STANDARD
åç §ããã®ã¯ãã¡ãã§ãã
AttributeDefinition - Amazon DynamoDB
読み込み/書き込みキャパシティーモード - Amazon DynamoDB
æå®ããŠããåãªãã·ã§ã³ã®æå³ã¯ã以äžã®æå³ã®ããã§ãã
--table-name
⊠ããŒãã«å--key-schema
⊠ããŒãã«ïŒãŸãã¯ã€ã³ããã¯ã¹ïŒã®äž»ããŒã®å®çŸ©--attribute-definitions
âŠ å±æ§ã®å®çŸ©--provisioned-throughput
⊠ããŒãã«ïŒãŸãã¯ã€ã³ããã¯ã¹ïŒã®ããããžã§ãã³ã°ãããã¹ã«ãŒããããæå®--billing-mode
ã§éžæå¯èœãªPROVISIONED
ïŒããã©ã«ãïŒãšPAY_PER_REQUEST
ã®ãã¡ãPROVISIONED
ãéžæããå Žåã¯æå®ãå¿ é
--table-class
⊠ããŒãã«ã¯ã©ã¹ãSTANDARD
ãšSTANDARD_INFREQUENT_ACCESS
ããéžæ
ãšããããšã¯ãããŒãã«Music
ã以äžã®å®çŸ©ã§äœã£ãŠããããšã«ãªããŸãã
Artist
ãããŒãã£ã·ã§ã³ããŒãSongTitle
ããœãŒãããŒãšããè€åäž»ããŒArtist
ãSongTitle
ã¯ãšãã«æååå- ç§éãããã®ã¹ã«ãŒãããã¯ãããããïŒåŒ·ãäžè²«æ§ãæã€ïŒèªã¿åãã®æå€§æ°ã10ãæžã蟌ã¿ã®æå€§æ°ã5
- ããŒãã«ã¯ã©ã¹ã¯æšæº
Amazon DynamoDBãJavaScriptïŒNode.jsïŒããæäœããŠã¿ã
ããŒãã«ãäœæããã®ã§ãããã°ã©ã ããã¢ã¯ã»ã¹ããŠã¿ãŸããããä»åã¯ãJavaScriptïŒNode.jsïŒïŒTypeScriptã§æ±ãããšã«ããŸãã
ããŒãã«äœæä»¥éã®ãã¡ãã®ã¹ãããããCRUDçšåºŠãŸã§è¡ã£ãŠããŸãããã
â»AWS SDK for JavaScriptã䜿ã£ãããã¥ã¡ã³ãããããŸããããã¡ãã¯åŸã§
DynamoDB の使用開始 - Amazon DynamoDB
AWS SDK for JavaScriptã¯ãv2ã䜿ãããšã«ããŸãã
AWS SDK for JavaScript とは - AWS SDK for JavaScript
File: README — AWS SDK for JavaScript
Class: AWS.DynamoDB — AWS SDK for JavaScript
ç°å¢ã¯ããã¡ãã
$ node --version v16.13.2 $ npm --version 8.1.2
Node.jsãããžã§ã¯ãã®ã»ããã¢ãããè¡ããŸãã確èªã¯ãã¹ãã³ãŒãã§è¡ãã®ã§ãJestãŸã§ã€ã³ã¹ããŒã«ã
$ npm init -y $ npm i -D typescript $ npm i -D -E prettier $ npm i -D @types/node@v16 $ npm i -D jest @types/jest $ npm i -D esbuild esbuild-jest $ mkdir src test
AWS SDK for JavaScript v2ã®ã€ã³ã¹ããŒã«ã
$ npm i aws-sdk
ä»åã®äŸåé¢ä¿ã¯ããã®ããã«ãªããŸããã
"devDependencies": { "@types/jest": "^27.4.0", "@types/node": "^16.11.21", "esbuild": "^0.14.14", "esbuild-jest": "^0.5.0", "jest": "^27.4.7", "prettier": "2.5.1", "typescript": "^4.5.5" }, "dependencies": { "aws-sdk": "^2.1066.0" }
TypeScriptã®èšå®ã
tsconfig.json
{ "compilerOptions": { "target": "esnext", "module": "commonjs", "lib": ["esnext"], "baseUrl": "./src", "outDir": "dist", "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, "noPropertyAccessFromIndexSignature": true, "esModuleInterop": true }, "include": [ "src" ] }
tsconfig.typecheck.conf
{ "extends": "./tsconfig", "compilerOptions": { "baseUrl": "./", "noEmit": true }, "include": [ "src", "test" ] }
Prettierã®èšå®ã
.prettierrc.json
{ "singleQuote": true }
Jestã®èšå®ã
jest.config.js
module.exports = { testEnvironment: 'node', transform: { "^.+\\.tsx?$": "esbuild-jest" } };
AWS SDK for JavaScript v2ã¯TypeScriptããµããŒãããŠãããããªã®ã§ãããå宣èšã®æ å ±ã«å°ã£ãããã¡ããèŠãŸãããã
https://github.com/aws/aws-sdk-js/blob/v2.1066.0/clients/dynamodb.d.ts
ããã§ãä»åãªãã£ãŠããã®ã§ãããAWS SDKã§DynamoDBã«ã¢ã¯ã»ã¹ããAPIã¯3çš®é¡ãããAWS SDK for JavaScriptã¯
äœã¬ãã«ã€ã³ã¿ãŒãã§ãŒã¹ãšããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã®2çš®é¡ããµããŒãããŠããŸãã
低レベルインターフェイス - Amazon DynamoDB
ドキュメントインターフェイス - Amazon DynamoDB
オブジェクト永続性インターフェイス - Amazon DynamoDB
ãŸãã¯ãäœã¬ãã«ã€ã³ã¿ãŒãã§ãŒã¹ã®æ¹ã䜿ã£ãŠãAWS CLIã®ããã¥ã¡ã³ããæš¡å£ããŠãããŸãã
ããŒã«ã«çã®Amazon DynamoDBã«æ¥ç¶ããæºå
ãŸãã¯ãå¿ èŠãªã¢ãžã¥ãŒã«ã®ã€ã³ããŒããšããŒã«ã«çã®Amazon DynamoDBã«æ¥ç¶ããæºåãããŸãããããããªæãã«ãªããŸããã
test/dynamodb.test.ts
import AWS from 'aws-sdk'; import { DeleteItemInput, GetItemInput, PutItemInput, QueryInput, UpdateItemInput, } from 'aws-sdk/clients/dynamodb'; const dynamodb = new AWS.DynamoDB({ credentials: { accessKeyId: 'fakeMyKeyId', secretAccessKey: 'fakeSecretAccessKey', }, region: 'ap-northeast-1', endpoint: 'http://localhost:8000', }); // ããã«ããã¹ããæžãïŒ
ãšã³ããã€ã³ãã®æå®ãå¿ èŠã«ãªããŸããã
ã§ã¯ãé²ããŠãããŸãã
ããŒã¿ãæžã蟌ã
æåã¯ãæžã蟌ã¿ããã
ステップ 2: コンソールまたは AWS CLI を使用して、テーブルにデータを書き込む - Amazon DynamoDB
ããã¥ã¡ã³ãã©ããã2ä»¶æžã蟌ãã§ã¿ãŸããããã¯DynamoDB#putItem
ã§è¡ããŸãã
test('write items', async () => { const params1: PutItemInput = { TableName: 'Music', Item: { Artist: { S: 'No One You Know', }, SongTitle: { S: 'Call Me Today', }, AlbumTitle: { S: 'Somewhat Famous', }, Awards: { N: '1', }, }, }; await dynamodb.putItem(params1).promise(); const params2: PutItemInput = { TableName: 'Music', Item: { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, AlbumTitle: { S: 'Songs About Life', }, Awards: { N: '10', }, }, }; await dynamodb.putItem(params2).promise(); });
S
ãšãN
ã¯ãå屿§ã®å€ãæåååãæ°å€åã§ããããšã衚ããŠããŸãã
ããŒã¿ãèªã¿èŸŒã
ããŒã¿ã®èªã¿èŸŒã¿ã
ステップ 3: テーブルからデータを読み込む - Amazon DynamoDB
DynamoDB#readItem
ã§ãããŒãæå®ããŠèªã¿èŸŒã圢ã«ãªãããã§ãã
test('read item', async () => { const params: GetItemInput = { TableName: 'Music', Key: { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, }, ConsistentRead: true, }; const item = await dynamodb.getItem(params).promise(); if (item.Item) { expect(item.Item['AlbumTitle']).toEqual({ S: 'Songs About Life', }); expect(item.Item['Awards']).toEqual({ N: '10' }); } else { throw new Error('fail'); } });
ã¡ãªã¿ã«ä»åã¯è€åäž»ããŒãªã®ã§ããã®æå®ãäžéå端ã ãšãšã©ãŒã«ãªããŸãã以äžã¯ããŒãã£ã·ã§ã³ããŒã®ã¿ãæå®ããŠããœãŒãããŒã
ããŠããŸããããããã¯å€±æããŸãã
test('read item, fail', async () => { const params: GetItemInput = { TableName: 'Music', Key: { Artist: { S: 'Acme Band', }, }, ConsistentRead: true, }; try { const item = await dynamodb.getItem(params).promise(); throw new Error('fail'); } catch (e) { const error = e as Error; expect(error.message).toBe( 'The number of conditions on the keys is invalid' ); } });
ããŒã¿ãæŽæ°ãã
ããŒã¿ã®æŽæ°ã
ステップ 4: テーブルのデータを更新する - Amazon DynamoDB
DynamoDB#updateItem
ã§è¡ããŸããSQLã®updateæã¿ãããªæãã§ããã
test('update item', async () => { const params: UpdateItemInput = { TableName: 'Music', Key: { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, }, ExpressionAttributeNames: { '#AT': 'AlbumTitle', }, ExpressionAttributeValues: { ':NEWVAL': { S: 'Updated Album Title', }, }, UpdateExpression: 'SET #AT = :NEWVAL', ReturnValues: 'ALL_NEW', }; const returnValue = await dynamodb.updateItem(params).promise(); expect(returnValue.Attributes).toEqual({ Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, AlbumTitle: { S: 'Updated Album Title', }, Awards: { N: '10', }, }); });
ãªããããã¢ã€ãã ãåçŽã«çœ®ãæããã ãã§ãããªããDynamoDB#putItem
ã§OKãªããã§ãã
Creates a new item, or replaces an old item with a new item. If an item that has the same primary key as the new item already exists in the specified table, the new item completely replaces the existing item.
ããŒã¿ãã¯ãšãªãã
ããŒã¿ã«å¯ŸããŠã¯ãšãªãå®è¡ããŠã¿ãŸãã
ステップ 5: テーブルのデータをクエリする - Amazon DynamoDB
ããã¯ãDynamoDB#query
ã§è¡ããŸãã
test('query', async () => { const params: QueryInput = { TableName: 'Music', KeyConditionExpression: 'Artist = :name', ExpressionAttributeValues: { ':name': { S: 'Acme Band', }, }, }; const result = await dynamodb.query(params).promise(); expect(result.Count).toBe(1); expect(result.ScannedCount).toBe(1); expect(result.ConsumedCapacity).toBeUndefined(); expect(result.Items).toEqual([ { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, AlbumTitle: { S: 'Updated Album Title', }, Awards: { N: '10', }, }, ]); });
ããŒã¿ãåé€ãã
æåŸã¯Getting Startedã®ããã¥ã¡ã³ãã«ã¯èšèŒããããŸãããããŒã¿ãåé€ããŠã¿ãŸãã
ããã¯ãDynamoDB#deleteItem
ã§è¡ããŸãã
test('delete item', async () => { const params: DeleteItemInput = { TableName: 'Music', Key: { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, }, }; const value = await dynamodb.deleteItem(params).promise(); expect(value).not.toBeNull(); const readParms: GetItemInput = { TableName: 'Music', Key: { Artist: { S: 'Acme Band', }, SongTitle: { S: 'Happy Day', }, }, ConsistentRead: true, }; const item = await dynamodb.getItem(params).promise(); expect(item.Item).toBeUndefined(); });
ã¢ã€ãã ãåé€åŸãèªã¿èŸŒã¿ãè¡ã£ãŠã¿ãŠè©²åœã®ã¢ã€ãã ãååŸã§ããªããªã£ãŠããããšã確èªã
ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã䜿ã£ãŠã¿ã
å ã»ã©ã¯AWS SDK for JavaScriptã§äœã¬ãã«ã€ã³ã¿ãŒãã§ãŒã¹ã®äœ¿ã£ãŠã¿ãŸããããæåŸã«ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã䜿ã£ãŠã¿ãããšæããŸãã
ドキュメントインターフェイス - Amazon DynamoDB
ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã䜿ããšãS
ãN
ãšãã£ãããŒã¿åã®æå®ãæžãå¿
èŠããªããªããèšè¿°ãç°¡åã«ãªããŸãã
AWS SDK for JavaScriptã§ã¯ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ãå©çšã§ããDocumentClient
ãšããã¯ã©ã¹ããã®æ©èœãæã¡ãŸãã
Class: AWS.DynamoDB.DocumentClient — AWS SDK for JavaScript
ãŸããAmazon DynamoDBã®JavaScriptçšã®Getting Startedã§ã¯ãããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã䜿ã£ããµã³ãã«ã³ãŒãã«ãªã£ãŠããŸãã
ステップ 1: JavaScript を使用して DynamoDB テーブルを作成する - Amazon DynamoDB
å宣èšã¯ãã¡ãã§ãã
https://github.com/aws/aws-sdk-js/blob/v2.1066.0/lib/dynamodb/document_client.d.ts
Amazon DynamoDBã®JavaScriptã®Getting Startedã®ãã¡ãCRUDãããããã£ãŠã¿ãŸãããã
ããŒãã«ã¯ãAWS CLIã§äœæããŠããããšã«ããŸãã
$ aws dynamodb create-table \ --endpoint-url http://localhost:8000 \ --table-name Movies \ --attribute-definitions \ AttributeName=year,AttributeType=N \ AttributeName=title,AttributeType=S \ --key-schema \ AttributeName=year,KeyType=HASH \ AttributeName=title,KeyType=RANGE \ --provisioned-throughput \ ReadCapacityUnits=5,WriteCapacityUnits=5 \ --table-class STANDARD
ãã¡ããè€åäž»ããŒã§ããã
ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã䜿ãããã®æºåã¯ããã¡ããAWS.DynamoDB.DocumentClient
ãšããé
眮ã«ãªã£ãŠããã®ã§ãããæåãã
DocumentClient
ã§äžæ°ã«import
ããããšã«ããŸããã
test/documentclient.test.ts
import { DocumentClient } from 'aws-sdk/clients/dynamodb'; import { Movie, Info } from '../src/movie'; const dynamodb = new DocumentClient({ credentials: { accessKeyId: 'fakeMyKeyId', secretAccessKey: 'fakeSecretAccessKey', }, region: 'ap-northeast-1', endpoint: 'http://localhost:8000', }); // ããã«ããã¹ããæžãïŒ
AWSã®ã¯ã¬ãã³ã·ã£ã«ããšã³ããã€ã³ãã¯ãDynamoDB
ãšåãããã«ã³ã³ã¹ãã©ã¯ã¿ã§æž¡ãããšãã§ããŸãã
ãã£ãããªã®ã§ãããŒã¿ã«é¢ããã¯ã©ã¹å®çŸ©ãè¡ãããšã«ããŸããã
src/movie.ts
export class Movie { year: number; title: string; info: Info; constructor(year: number, title: string, info: Info) { this.year = year; this.title = title; this.info = info; } } export class Info { plot: string; rating: number; actors?: string[] = undefined; constructor(plot: string, rating: number, actors?: string[]) { this.plot = plot; this.rating = rating; this.actors = actors; } }
ãã¡ãã¯ãç°¡åã«æžããŠãããŸãã
ããŒã¿ïŒã¢ã€ãã ïŒã®æžã蟌ã¿ã
test('write items', async () => { const movie = new Movie( 2015, 'The Big New Movie', new Info('Nothing happens at all.', 0) ); const params: DocumentClient.PutItemInput = { TableName: 'Movies', Item: movie, }; return await dynamodb.put(params).promise(); });
ããŒã¿ã®èªã¿èŸŒã¿ã
test('read item', async () => { const params: DocumentClient.GetItemInput = { TableName: 'Movies', Key: { year: 2015, title: 'The Big New Movie', }, ConsistentRead: true, }; const value = await dynamodb.get(params).promise(); const movie = value.Item as Movie; expect(movie.year).toBe(2015); expect(movie.title).toBe('The Big New Movie'); expect(movie.info.plot).toBe('Nothing happens at all.'); expect(movie.info.rating).toBe(0); });
æŽæ°ã
test('update item', async () => { const params: DocumentClient.UpdateItemInput = { TableName: 'Movies', Key: { year: 2015, title: 'The Big New Movie', }, ExpressionAttributeValues: { ':r': 5.5, ':p': 'Everything happens all at once.', ':a': ['Larry', 'Moe', 'Curly'], }, UpdateExpression: 'set info.rating = :r, info.plot = :p, info.actors = :a', ReturnValues: 'UPDATED_NEW', }; const value = await dynamodb.update(params).promise(); if (value.Attributes) { const info = value.Attributes['info'] as Info; expect(info.plot).toBe('Everything happens all at once.'); expect(info.rating).toBe(5.5); expect(info.actors).toEqual(['Larry', 'Moe', 'Curly']); } else { throw new Error('fail'); } });
ãããåŠçã§ã®ããŒã¿ç»é²ãšãèªã¿èŸŒã¿ã§ã®ç¢ºèªã
test('batch write items', async () => { const movies = [ new Movie( 2013, 'Rush', new Info( 'A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.', 8.3 ) ), new Movie( 2012, 'The Dark Knight Rises', new Info( 'Eight years on, a new evil rises from where the Batman and Commissioner Gordon tried to bury it, causing the Batman to resurface and fight to protect Gotham City... the very city which brands him an enemy.', 8.6 ) ), ]; const params: DocumentClient.BatchWriteItemInput = { RequestItems: { Movies: movies.map((m) => { return { PutRequest: { Item: m } }; }), }, }; const writed = await dynamodb.batchWrite(params).promise(); const readParams1: DocumentClient.GetItemInput = { TableName: 'Movies', Key: { year: 2013, title: 'Rush', }, ConsistentRead: true, }; const value1 = await dynamodb.get(readParams1).promise(); const movie1 = value1.Item as Movie; expect(movie1.year).toBe(2013); expect(movie1.title).toBe('Rush'); expect(movie1.info.plot).toBe( 'A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.' ); expect(movie1.info.rating).toBe(8.3); const readParams2: DocumentClient.GetItemInput = { TableName: 'Movies', Key: { year: 2012, title: 'The Dark Knight Rises', }, ConsistentRead: true, }; const value2 = await dynamodb.get(readParams2).promise(); const movie2 = value2.Item as Movie; expect(movie2.year).toBe(2012); expect(movie2.title).toBe('The Dark Knight Rises'); expect(movie2.info.plot).toBe( 'Eight years on, a new evil rises from where the Batman and Commissioner Gordon tried to bury it, causing the Batman to resurface and fight to protect Gotham City... the very city which brands him an enemy.' ); expect(movie2.info.rating).toBe(8.6); });
ããŒã¿ã®åé€ãšç¢ºèªã
test('delete item', async () => { const params: DocumentClient.DeleteItemInput = { TableName: 'Movies', Key: { year: 2015, title: 'The Big New Movie', }, }; const value = await dynamodb.delete(params).promise(); expect(value).not.toBeNull(); const readParams: DocumentClient.GetItemInput = { TableName: 'Movies', Key: { year: 2015, title: 'The Big New Movie', }, ConsistentRead: true, }; const readValue = await dynamodb.get(readParams).promise(); expect(readValue.Item).toBeUndefined(); });
é·ããªã£ãŠããã®ã§ãä»åã¯ãã®ãããã§ã
ãŸãšã
ããŒã«ã«çã䜿ã£ãŠãç°¡åã«Amazon DynamoDBã詊ããŠã¿ãŸããã
å€å°é°å²æ°ã¯ããã£ãŠããŸããããã¯ãšãªãã¹ãã£ã³ã¯ãŸãä»åºŠè©ŠããŠã¿ããããªãšæããŸãã
ãŸãã䜿çšããã€ã³ã¿ãŒãã§ãŒã¹ã¯ããã¥ã¡ã³ãã€ã³ã¿ãŒãã§ãŒã¹ã§è¯ãããªãšæããŸãã
ã¡ãã£ãšãã€ãæ £ããŠãã£ãŠã¿ãŸãããã