├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── issue-template.md
└── workflows
│ └── main.yaml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── SECURITY.md
├── archived
├── LoadS3toDynamoDB
│ ├── README.md
│ └── load.py
└── README.md
├── examples
├── Bedrock
│ ├── Langchain
│ │ ├── chat_history.ipynb
│ │ └── img
│ │ │ ├── chatbot.png
│ │ │ └── echo.png
│ └── README.md
├── NERDS
│ ├── README.md
│ ├── basic-template
│ │ ├── README.md
│ │ ├── basic-backend
│ │ │ ├── .pre-commit-config.yaml
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── documentation
│ │ │ │ ├── Darn-basic-stack.gif
│ │ │ │ └── TaskMaster.png
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── retire.txt
│ │ │ │ └── server.js
│ │ └── basic-frontend
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── index.html
│ │ │ ├── logo192.png
│ │ │ ├── logo512.png
│ │ │ ├── manifest.json
│ │ │ └── robots.txt
│ │ │ └── src
│ │ │ ├── App.js
│ │ │ ├── components
│ │ │ └── Task
│ │ │ │ ├── TaskCard.js
│ │ │ │ ├── TaskForm.js
│ │ │ │ └── TaskList.js
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ └── styles.js
│ ├── enhanced-template
│ │ ├── README.md
│ │ ├── enhanced-backend
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ ├── documentation
│ │ │ │ ├── enhanced-app.png
│ │ │ │ ├── enhanced-backend.cast
│ │ │ │ └── enhanced-backend.gif
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── items.json
│ │ │ │ ├── populate.js
│ │ │ │ └── server.js
│ │ └── enhanced-frontend
│ │ │ ├── README.md
│ │ │ ├── eslint.config.js
│ │ │ ├── index.html
│ │ │ ├── package.json
│ │ │ ├── public
│ │ │ └── vite.svg
│ │ │ ├── src
│ │ │ ├── App.css
│ │ │ ├── App.jsx
│ │ │ ├── assets
│ │ │ │ └── react.svg
│ │ │ ├── components
│ │ │ │ └── Task
│ │ │ │ │ ├── TaskCard.jsx
│ │ │ │ │ ├── TaskForm.jsx
│ │ │ │ │ └── TaskList.jsx
│ │ │ ├── index.css
│ │ │ ├── main.jsx
│ │ │ └── styles.js
│ │ │ └── vite.config.js
│ └── recipe-example
│ │ ├── README.md
│ │ └── backend
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── buildspec.yml
│ │ ├── docker-compose.yml
│ │ ├── docker
│ │ └── dynamodb
│ │ │ └── shared-local-instance.db
│ │ ├── documentation
│ │ ├── demo-api.gif
│ │ └── demo.gif
│ │ ├── env.json
│ │ ├── package.json
│ │ ├── samconfig.toml
│ │ ├── src
│ │ ├── package.json
│ │ ├── recipes
│ │ │ ├── create
│ │ │ │ └── index.js
│ │ │ ├── delete
│ │ │ │ └── index.js
│ │ │ ├── get
│ │ │ │ └── index.js
│ │ │ ├── list
│ │ │ │ └── index.js
│ │ │ └── update
│ │ │ │ └── index.js
│ │ └── users
│ │ │ ├── create
│ │ │ └── index.js
│ │ │ ├── delete
│ │ │ └── index.js
│ │ │ ├── get
│ │ │ └── index.js
│ │ │ └── update
│ │ │ └── index.js
│ │ └── template.yaml
├── README.md
├── SDK
│ ├── Operations.md
│ ├── README.md
│ ├── dotnet
│ │ ├── README.md
│ │ └── sdk_v2
│ │ │ ├── DotnetSamples.csproj
│ │ │ ├── DotnetSamples.sln
│ │ │ ├── Models
│ │ │ └── CustomerOrder.cs
│ │ │ ├── Operations.md
│ │ │ ├── WorkingWithItems
│ │ │ ├── BatchGetItem.cs
│ │ │ ├── BatchWriteItem.cs
│ │ │ ├── DeleteItem.cs
│ │ │ ├── DeleteItemConditional.cs
│ │ │ ├── GetItem.cs
│ │ │ ├── PutItem.cs
│ │ │ ├── PutItemConditional.cs
│ │ │ ├── TransactGetItems.cs
│ │ │ ├── TransactWriteItems.cs
│ │ │ ├── UpdateItem.cs
│ │ │ └── UpdateItemConditional.cs
│ │ │ ├── WorkingWithQueries
│ │ │ ├── QueryConsistentRead.cs
│ │ │ ├── QueryConsumedCapacity.cs
│ │ │ ├── QueryCount.cs
│ │ │ ├── QueryFilterExpression.cs
│ │ │ └── QueryProjectionExpression.cs
│ │ │ └── WorkingWithTables
│ │ │ └── CreateTableProvisioned.cs
│ ├── golang
│ │ ├── Operations.md
│ │ ├── README.md
│ │ └── sdk_v1
│ │ │ ├── WorkingWithItems
│ │ │ ├── batchGetItem.go
│ │ │ ├── batchWriteItem.go
│ │ │ ├── deleteItem.go
│ │ │ ├── deleteItemConditional.go
│ │ │ ├── getItem.go
│ │ │ ├── putItem.go
│ │ │ ├── putItemConditional.go
│ │ │ ├── updateItem.go
│ │ │ └── updateItemConditional.go
│ │ │ └── WorkingWithTables
│ │ │ ├── addGlobalTableRegion
│ │ │ └── addGlobalTableRegion.go
│ │ │ ├── addProvisionedCapacity
│ │ │ └── addProvisionedCapacity.go
│ │ │ ├── changeTableToOnDemand
│ │ │ └── changeTableToOnDemand.go
│ │ │ ├── changeTableToProvisioned
│ │ │ └── changeTableToProvisioned.go
│ │ │ ├── createGlobalTable
│ │ │ └── createGlobalTable.go
│ │ │ ├── createTableOnDemand
│ │ │ └── createTableOnDemand.go
│ │ │ ├── createTableProvisioned
│ │ │ └── createTableProvisioned.go
│ │ │ ├── deleteGlobalTableRegion
│ │ │ └── deleteGlobalTableRegion.go
│ │ │ ├── deleteTable
│ │ │ └── deleteTable.go
│ │ │ ├── describeGlobalTable
│ │ │ └── describeGlobalTable.go
│ │ │ ├── describeLimits
│ │ │ └── describeLimits.go
│ │ │ ├── describeTable
│ │ │ └── describeTable.go
│ │ │ ├── disableAutoscaling
│ │ │ └── disableAutoscaling.go
│ │ │ ├── disableStreams
│ │ │ └── disableStreams.go
│ │ │ ├── enableAutoscaling
│ │ │ └── enableAutoscaling.go
│ │ │ ├── enableStreams
│ │ │ └── enableStreams.go
│ │ │ ├── listTables
│ │ │ └── listTables.go
│ │ │ ├── updateAutoscaling
│ │ │ └── updateAutoscaling.go
│ │ │ └── updateGlobalTable
│ │ │ └── updateGlobalTable.go
│ ├── java
│ │ ├── Operations.md
│ │ ├── README.md
│ │ └── sdk_v1
│ │ │ ├── control_plane
│ │ │ └── WorkingWithTables
│ │ │ │ ├── AddProvisionedCapacity.java
│ │ │ │ ├── CreateTableOnDemand.java
│ │ │ │ ├── CreateTableProvisioned.java
│ │ │ │ ├── DeleteTable.java
│ │ │ │ ├── DescribeLimits.java
│ │ │ │ ├── DescribeTable.java
│ │ │ │ ├── ListTables.java
│ │ │ │ ├── TableChangeToOnDemand.java
│ │ │ │ └── TableChangeToOnProvisioned.java
│ │ │ └── data_plane
│ │ │ ├── CustomUseCases
│ │ │ ├── OverrideCredentialsProviderOnPutItemRequest.java
│ │ │ └── README.md
│ │ │ ├── WorkingWithIndexes
│ │ │ └── TableAsyncQueryIndex.java
│ │ │ ├── WorkingWithItems
│ │ │ ├── BatchGetItem.java
│ │ │ ├── BatchWriteItem.java
│ │ │ ├── DeleteItem.java
│ │ │ ├── GetItem.java
│ │ │ ├── PutItem.java
│ │ │ ├── PutItemConditional.java
│ │ │ ├── TransactGetItem.java
│ │ │ ├── TransactWriteItem.java
│ │ │ ├── UpdateItem.java
│ │ │ └── UpdateItemConditional.java
│ │ │ ├── WorkingWithQueries
│ │ │ ├── QueryConsistentRead.java
│ │ │ ├── QueryWithFilterExpression.java
│ │ │ ├── QueryWithProjectionExpression.java
│ │ │ ├── QueryWithSortKey.java
│ │ │ └── TableAsyncQuery.java
│ │ │ └── WorkingWithScans
│ │ │ └── TableAsyncScan.java
│ ├── kotlin
│ │ ├── Operations.md
│ │ ├── README.md
│ │ ├── control_plane
│ │ │ └── WorkingWithTables
│ │ │ │ └── .todo
│ │ └── data_plane
│ │ │ ├── WorkingWithIndexes
│ │ │ └── .todo
│ │ │ ├── WorkingWithItems
│ │ │ └── .todo
│ │ │ ├── WorkingWithQueries
│ │ │ └── .todo
│ │ │ ├── WorkingWithScans
│ │ │ └── .todo
│ │ │ └── WorkingWithStreams
│ │ │ └── .todo
│ ├── node.js
│ │ ├── Operations.md
│ │ ├── README.md
│ │ └── sdk_v3
│ │ │ ├── control_plane
│ │ │ ├── WorkingWithBackups
│ │ │ │ ├── CreateOn-DemandBackup.js
│ │ │ │ ├── DeleteBackup.js
│ │ │ │ └── DescribeBackup.js
│ │ │ ├── WorkingWithIndexes
│ │ │ │ ├── CreateIndex.js
│ │ │ │ ├── DeleteIndex.js
│ │ │ │ └── UpdateIndexProvisionedCapacity.js
│ │ │ └── WorkingWithTables
│ │ │ │ ├── add-global-table-region.js
│ │ │ │ ├── add_provisioned_capacity.js
│ │ │ │ ├── create-global-table.js
│ │ │ │ ├── create_table_on_demand.js
│ │ │ │ ├── create_table_provisioned.js
│ │ │ │ ├── delete-global-table-region.js
│ │ │ │ ├── delete_table.js
│ │ │ │ ├── describe-global-table-and-global-table-settings.js
│ │ │ │ ├── describe_limits.js
│ │ │ │ ├── describe_table.js
│ │ │ │ ├── disable_auto_scaling.js
│ │ │ │ ├── disable_streams.js
│ │ │ │ ├── enable-global-tables.js
│ │ │ │ ├── enable_auto_scaling_v2.js
│ │ │ │ ├── enable_auto_scaling_v3.js
│ │ │ │ ├── enable_streams.js
│ │ │ │ ├── export_table_s3.js
│ │ │ │ ├── list_tables.js
│ │ │ │ ├── table_change_to_on_demand.js
│ │ │ │ ├── table_change_to_provisioned.js
│ │ │ │ ├── update-global-table-and-global-table-settings.js
│ │ │ │ ├── update_auto_scaling_v2.js
│ │ │ │ └── update_auto_scaling_v3.js
│ │ │ └── data_plane
│ │ │ ├── WorkingWithCustomBackoffRetry
│ │ │ └── exponential_backoff_retry_get_item.js
│ │ │ ├── WorkingWithItems
│ │ │ ├── batch-get.js
│ │ │ ├── batch-write.js
│ │ │ ├── delete-item.js
│ │ │ ├── get-item-low-level.js
│ │ │ ├── get-item.js
│ │ │ ├── put-item-conditional.js
│ │ │ ├── put-item.js
│ │ │ ├── transact-get.js
│ │ │ ├── transact-write.js
│ │ │ ├── update-item-conditional.js
│ │ │ └── update-item.js
│ │ │ ├── WorkingWithPartiQL
│ │ │ ├── batch-execute-statement.js
│ │ │ ├── execute-statement.js
│ │ │ ├── execute-transaction.js
│ │ │ ├── paginated-all-data.js
│ │ │ ├── sanitization-for-sql-injection.js
│ │ │ ├── simple-select-statement.js
│ │ │ └── sql-injection.js
│ │ │ ├── WorkingWithQueries
│ │ │ ├── query-consistent-read.js
│ │ │ ├── query-filter-expression.js
│ │ │ ├── query-key-condition-expression-begins-with-sort-order.js
│ │ │ ├── query-key-condition-expression-begins-with.js
│ │ │ ├── query-key-condition-expression-between-dates.js
│ │ │ ├── query-key-condition-expression-between-numbers.js
│ │ │ ├── query-key-condition-expression-equals.js
│ │ │ ├── query-key-condition-expression-greater-equal.js
│ │ │ ├── query-key-condition-expression-greater.js
│ │ │ ├── query-key-condition-expression-less-equal.js
│ │ │ ├── query-key-condition-expression-less.js
│ │ │ ├── query-projection-expression.js
│ │ │ ├── query-return-consumed-capacity.js
│ │ │ ├── query-scan-count.js
│ │ │ ├── query-with-pagination-all-data.js
│ │ │ ├── query-with-pagination-backwards.js
│ │ │ └── query-with-pagination.js
│ │ │ ├── WorkingWithScans
│ │ │ ├── scan-fetch-all-pagination.js
│ │ │ └── scan-parallel-segments.js
│ │ │ └── WorkingWithStreams
│ │ │ └── read-stream.js
│ ├── python
│ │ ├── Operations.md
│ │ ├── README.md
│ │ ├── WorkingWithTestData
│ │ │ └── test_data_generator.py
│ │ ├── control_plane
│ │ │ ├── WorkingWithIndexes
│ │ │ │ └── add_gsi.py
│ │ │ └── WorkingWithTables
│ │ │ │ ├── add_global_table_region.py
│ │ │ │ ├── add_provisioned_capacity.py
│ │ │ │ ├── create_table_on-demand.py
│ │ │ │ ├── create_table_provisioned.py
│ │ │ │ ├── delete_global_table_region.py
│ │ │ │ ├── delete_table.py
│ │ │ │ ├── describe_limits.py
│ │ │ │ ├── describe_table.py
│ │ │ │ ├── disable_auto-scaling.py
│ │ │ │ ├── enable_auto-scaling.py
│ │ │ │ ├── enable_continuous_backups.py
│ │ │ │ ├── enable_streams.py
│ │ │ │ ├── export_table_s3.py
│ │ │ │ ├── list_tables.py
│ │ │ │ ├── update_table_on-demand.py
│ │ │ │ └── update_table_provisioned.py
│ │ └── data_plane
│ │ │ ├── WorkingWithCustomBackoffRetry
│ │ │ └── exponential_backoff_retry_get_item.py
│ │ │ ├── WorkingWithItems
│ │ │ ├── batch_get.py
│ │ │ ├── batch_write.py
│ │ │ ├── delete_item.py
│ │ │ ├── delete_item_conditional.py
│ │ │ ├── get_item.py
│ │ │ ├── put_item.py
│ │ │ ├── put_item_conditional.py
│ │ │ ├── transact_get.py
│ │ │ ├── transact_write.py
│ │ │ ├── update_item_conditional.py
│ │ │ └── updating_item.py
│ │ │ ├── WorkingWithPartiQL
│ │ │ ├── batch-execute-statement.py
│ │ │ ├── execute-statement.py
│ │ │ ├── execute-transaction.py
│ │ │ ├── paginated-query-batch-execute-statement.py
│ │ │ ├── paginated-select-statement.py
│ │ │ └── simple-select-statement.py
│ │ │ ├── WorkingWithQueries
│ │ │ ├── pagination.py
│ │ │ ├── query-consistent-read.py
│ │ │ ├── query-return-consumed-capacity.py
│ │ │ ├── query-scan-count.py
│ │ │ ├── query_begins_with.py
│ │ │ ├── query_equals.py
│ │ │ ├── query_filter_expression.py
│ │ │ └── query_projection_expression.py
│ │ │ └── WorkingWithScans
│ │ │ ├── scan_filter_expression.py
│ │ │ ├── scan_paginate.py
│ │ │ ├── scan_parallel.py
│ │ │ ├── scan_projection_expression.py
│ │ │ ├── scan_simple.py
│ │ │ └── scan_with_paginator.py
│ └── rust
│ │ ├── .gitignore
│ │ ├── Operations.md
│ │ ├── README.md
│ │ ├── control_plane
│ │ └── working_with_tables
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ ├── create-table-on-demand
│ │ │ └── main.rs
│ │ │ ├── delete-table
│ │ │ └── main.rs
│ │ │ ├── describe-table
│ │ │ └── main.rs
│ │ │ └── list-tables
│ │ │ └── main.rs
│ │ └── data_plane
│ │ ├── working_with_indexes
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ │ ├── create-index
│ │ │ └── main.rs
│ │ │ ├── delete-index
│ │ │ └── main.rs
│ │ │ └── query-index
│ │ │ └── main.rs
│ │ ├── working_with_items
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ ├── batch-get
│ │ │ └── main.rs
│ │ │ ├── batch-write
│ │ │ └── main.rs
│ │ │ ├── conditional-put-item
│ │ │ └── main.rs
│ │ │ ├── conditional-update-item
│ │ │ └── main.rs
│ │ │ ├── delete-item
│ │ │ └── main.rs
│ │ │ ├── get-item
│ │ │ └── main.rs
│ │ │ ├── put-item
│ │ │ └── main.rs
│ │ │ ├── transact-get
│ │ │ └── main.rs
│ │ │ ├── transact-put
│ │ │ └── main.rs
│ │ │ └── update-item
│ │ │ └── main.rs
│ │ ├── working_with_queries
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ │ ├── prepare-query-data
│ │ │ └── main.rs
│ │ │ ├── query-consistent-read
│ │ │ └── main.rs
│ │ │ ├── query-consumed-capacity
│ │ │ └── main.rs
│ │ │ ├── query-projection
│ │ │ └── main.rs
│ │ │ └── query-scan-filter
│ │ │ └── main.rs
│ │ ├── working_with_scans
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ └── src
│ │ │ ├── scan-in-parallel
│ │ │ └── main.rs
│ │ │ └── scan-with-pagination
│ │ │ └── main.rs
│ │ └── working_with_streams
│ │ ├── Cargo.toml
│ │ └── src
│ │ ├── disable-update-streams
│ │ └── main.rs
│ │ └── enable-update-streams
│ │ └── main.rs
└── hedging
│ └── java
│ └── ddb-hedging-sample
│ ├── .gitignore
│ ├── README.md
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── dynamodbhedging
│ │ │ ├── DDBHedgingRequestHandler.java
│ │ │ └── DynamoDBHedgedQuery.java
│ └── resources
│ │ └── log4j.properties
│ └── test
│ └── java
│ └── com
│ └── example
│ └── dynamodbhedging
│ └── DynamoDBHedgedQueryTest.java
├── infrastructure_as_code
├── README.md
├── cdk
│ ├── DynamoDBCustomMetrics
│ │ ├── README.md
│ │ ├── app.py
│ │ ├── cdk.json
│ │ ├── dynamodb_custom_metrics
│ │ │ ├── __init__.py
│ │ │ └── dynamodb_custom_metrics_stack.py
│ │ ├── lambda
│ │ │ └── lambda_function.py
│ │ ├── requirements.txt
│ │ └── screenshot.png
│ └── README.md
├── cloudformation
│ ├── README.md
│ └── global_tables
│ │ ├── GlobalTable_OnDemand.json
│ │ ├── GlobalTable_OnDemand.yml
│ │ ├── GlobalTable_Provisioned.json
│ │ ├── GlobalTable_Provisioned.yml
│ │ └── README.md
└── security
│ ├── DynamoDBIAMPolicies
│ ├── AmazonDynamoDB+DAXDataFullAccess.json
│ ├── AmazonDynamoDBAcceleratorDataFullAccess.json
│ ├── AmazonDynamoDBAppendOnlyAccess.json
│ ├── AmazonDynamoDBDataFullAccess.json
│ ├── AmazonDynamoDBInfrastructureFullAccess.json
│ └── AmazonDynamoDBStreamsOnlyAccess.json
│ └── README.md
├── schema_design
├── BuildingBlocks
│ └── WriteSharding
│ │ ├── README.md
│ │ └── python
│ │ └── WriteShardingExample.py
├── README.md
└── SchemaExamples
│ ├── ChatSystem
│ ├── ChatSystemSchema.json
│ └── README.md
│ ├── ComplainManagement
│ └── ComplaintManagementSchema.json
│ ├── ConnectedVehicles
│ ├── ConnectedVehiclesSchema.json
│ └── README.md
│ ├── GamingPlayerProfiles
│ └── GamePlayerProfilesSchema.json
│ ├── ReocurringPayments
│ └── ReocurringPaymentsSchema.json
│ ├── SessionManagement
│ ├── README.md
│ └── SessionManagementSchema.json
│ └── SocialNetwork
│ ├── README.md
│ └── SocialNetworkSchema.json
├── scripts
├── PrintDistinctPKs
│ ├── LoadMaxValues
│ │ ├── java
│ │ │ ├── Dockerfile
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src
│ │ │ │ └── main
│ │ │ │ └── java
│ │ │ │ └── org
│ │ │ │ └── example
│ │ │ │ └── LoadMaxValues.java
│ │ ├── nodejs
│ │ │ ├── loadMaxValues.js
│ │ │ └── package.json
│ │ └── python
│ │ │ └── load_max_values.py
│ ├── Printer
│ │ ├── java
│ │ │ ├── Dockerfile
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src
│ │ │ │ └── main
│ │ │ │ └── java
│ │ │ │ └── org
│ │ │ │ └── example
│ │ │ │ └── PrintDistinctPKs.java
│ │ ├── nodejs
│ │ │ ├── package.json
│ │ │ └── print_distinct_pks.js
│ │ └── python
│ │ │ └── print_distinct_pks.py
│ ├── README.md
│ └── RandomLoader
│ │ └── load_random_data.py
├── README.md
├── docker
│ ├── README.md
│ └── docker-compose.yml
└── nosqlworkbenchscript
│ ├── README.md
│ └── create-workbench-import.js
└── workshops
├── README.md
├── global-serverless
├── .chalice
│ └── config.json
├── README.md
├── app.py
├── requirements-dev.txt
├── requirements.txt
├── s3.sh
├── sample-data.json
├── test.py
└── web
│ ├── favicon.ico
│ ├── globalflix.css
│ ├── globalflix.html
│ ├── globalflix.js
│ ├── index.css
│ ├── index.html
│ ├── index.js
│ ├── logo.png
│ ├── player.css
│ ├── player.html
│ └── player.js
└── relational-migration
├── .chalice
├── config.json
└── relational-migration-policy.json
├── README.md
├── app.py
├── chalicelib
├── __init__.py
├── dynamodb_calls.py
└── mysql_calls.py
├── load
├── jobs
│ ├── Customers.py
│ ├── Ledger.py
│ ├── OrderLines.py
│ ├── Orders.py
│ ├── Products.py
│ ├── Reps.py
│ └── job1.py
├── load.py
└── test.py
├── migrate.sh
├── mysql_desc_ddb.py
├── mysql_s3.py
├── requirements.txt
├── setenv.sh
├── setup_tables.sh
├── source-tables
├── create_tables.sh
├── create_tables.sql
└── create_views.sql
├── target-tables
├── drop_tables.sh
└── list_imports.sh
├── test_delete.py
├── test_desc.py
├── test_get.py
├── test_query.py
├── test_read.py
├── test_scan.py
├── test_sql.py
├── test_tables.py
├── test_update.py
├── test_view.py
├── test_write.py
└── webapp
├── api.js
├── form.js
├── generate.js
├── index.css
├── index.html
├── index.js
└── sql-samples.js
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG] - "
5 | labels: bug, needs triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is. This should include a URL link to the section of the repository that contains the example with the bug.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Run steps '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - SDK Version [e.g. 22]
29 | - Specific Language configuration
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[Feature Request] - "
5 | labels: needs triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/issue-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Issue Template
3 | about: Describe this issue template's purpose here.
4 | title: "[Issue] - "
5 | labels: needs triage
6 | assignees: ''
7 |
8 | ---
9 |
10 | READ BEFORE SUBMITTING THIS ISSUE:
11 |
12 | 99.9% of the cases you should be creating either a Bug or a Feature request:
13 | - Bugs represent something is not working as expected on the existing code and you need to fix it.
14 | - Feature request represents anything new that you want to see in the repository.
15 | - This issue template is for anything that doesn't fit in between those two.
16 |
17 | **Description**: A clear description of your issue, including steps to reproduce. This description also needs to explain why this is not a bug and why you are considering this is a different type of issue.
18 |
19 | **Impact**: Describe the impact of this issue.
20 |
21 | **Context**: Provide any additional context you want to share.
22 |
--------------------------------------------------------------------------------
/.github/workflows/main.yaml:
--------------------------------------------------------------------------------
1 | name: PushLSQLWebApp
2 |
3 | permissions:
4 | id-token: write
5 | on:
6 | push:
7 | branches:
8 | - master
9 |
10 | jobs:
11 | buildAndDeploy:
12 | runs-on: ubuntu-latest
13 | env:
14 | STEP_S3_BUCKET: amazon-dynamodb-labs.com
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v3
18 | with:
19 | submodules: 'recursive'
20 | fetch-depth: '0'
21 | - name: Setup Python
22 | uses: actions/setup-python@v4
23 | with:
24 | python-version: '3.10'
25 | - name: Configure AWS Credentials
26 | uses: aws-actions/configure-aws-credentials@v1
27 | with:
28 | aws-region: us-east-1
29 | role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
30 | - name: S3SyncStaticWeb
31 | run: aws s3 sync ./workshops/relational-migration/webapp/ s3://amazon-dynamodb-labs-static/static/relational-migration/web/
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 | python/ReadMe.rst
4 | python/venv
5 | tmpCredentials.json
6 | **/.vscode/**
7 | **/node_modules/**
8 | get-temp-credentials.sh
9 | package-lock.json
10 | .idea/*
11 | *.swp
12 | **/.vs/
13 | **/bin/
14 | **/obj/
15 | **/launchSettings.json
16 | **/.idea/*
17 |
18 |
19 | **/.idea/
20 | **/.DS_Store
21 | **/.chalice/deployments/
22 | **/.chalice/deployed/
23 | workshops/relational-migration/target-tables/
24 | workshops/relational-migration/syncs3.sh
25 | workshops/relational-migration/.chalice/config.json
26 | workshops/relational-migration/setenv.sh
27 | workshops/relational-migration/setenvd.sh
28 | workshops/relational-migration/source-tables/app_db.*
29 |
30 | **/.aws-sam/
31 | **.db
32 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 |
3 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
4 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
5 | opensource-codeofconduct@amazon.com with any additional questions or comments.
6 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT No Attribution
2 |
3 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so.
10 |
11 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
13 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
15 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2013-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
4 |
5 | http://aws.amazon.com/apache2.0/
6 |
7 | or in the "LICENSE.txt" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
8 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | ## Reporting Security Issues
2 |
3 | We take all security reports seriously. When we receive such reports, we will investigate and subsequently address any potential vulnerabilities as quickly as possible. If you discover a potential security issue in this project, please notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/) or directly via email to [AWS Security](mailto:aws-security@amazon.com). Please do not create a public GitHub issue in this project.
4 |
--------------------------------------------------------------------------------
/examples/Bedrock/Langchain/img/chatbot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/Bedrock/Langchain/img/chatbot.png
--------------------------------------------------------------------------------
/examples/Bedrock/Langchain/img/echo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/Bedrock/Langchain/img/echo.png
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/README.md:
--------------------------------------------------------------------------------
1 | # Basic Template
2 |
3 | In this example you will build the TaskMaster application!
4 |
5 | 
6 |
7 | To execute this project please:
8 |
9 | 1. Open the [basic-backend](./basic-backend/README.md) folder with instructions to execute the backend locally.
10 | 2. Open the [basic-frontend](./basic-frontend/README.md) folder with instructions to execute the front end and run your web applicaation locally.
11 |
12 | We have recorded a video in our [DynamoDB Nuggets]() playlist that talks about this example in detail.
13 |
14 | [](https://youtu.be/u2JtuoTA7Vk)
15 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-backend/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v4.6.0
4 | hooks:
5 | - id: trailing-whitespace
6 | - id: end-of-file-fixer
7 | - id: check-json
8 | - id: detect-aws-credentials
9 | args: ["--allow-missing-credentials"]
10 | - id: detect-private-key
11 | - repo: https://github.com/Yelp/detect-secrets
12 | rev: v1.5.0
13 | hooks:
14 | - id: detect-secrets
15 | args: ["--baseline", ".secrets.baseline"]
16 | exclude: Pipfile.lock
17 | - repo: https://github.com/pre-commit/mirrors-prettier
18 | rev: v3.1.0
19 | hooks:
20 | - id: prettier
21 | - repo: https://github.com/awslabs/cfn-python-lint
22 | rev: v1.8.2 # The version of cfn-lint to use
23 | hooks:
24 | - id: cfn-python-lint
25 | files: templates/.*\.(json|yml|yaml)$
26 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-backend/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Esteban Serna
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-backend/documentation/Darn-basic-stack.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/basic-template/basic-backend/documentation/Darn-basic-stack.gif
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-backend/documentation/TaskMaster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/basic-template/basic-backend/documentation/TaskMaster.png
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-backend/src/retire.txt:
--------------------------------------------------------------------------------
1 | {"version":"5.1.3","start":"2024-08-15T19:18:49.327Z","data":[],"messages":[],"errors":[],"time":0.021}
2 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "basic-frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^18.3.1",
7 | "react-dom": "^18.3.1",
8 | "react-icons": "^5.2.1",
9 | "react-scripts": "^5.0.1",
10 | "web-vitals": "^4.2.2"
11 | },
12 | "scripts": {
13 | "start": "react-scripts start",
14 | "build": "react-scripts build",
15 | "test": "react-scripts test",
16 | "eject": "react-scripts eject"
17 | },
18 | "browserslist": {
19 | "production": [
20 | ">0.2%",
21 | "not dead",
22 | "not op_mini all"
23 | ],
24 | "development": [
25 | "last 1 chrome version",
26 | "last 1 firefox version",
27 | "last 1 safari version"
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/basic-template/basic-frontend/public/favicon.ico
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/basic-template/basic-frontend/public/logo192.png
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/basic-template/basic-frontend/public/logo512.png
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/src/components/Task/TaskCard.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { FaTrash } from "react-icons/fa";
3 | import styles from "../../styles";
4 |
5 | function TaskCard({ task, onDelete }) {
6 | return (
7 |
8 |
9 |
{task.title}
10 |
13 |
14 |
{task.description}
15 |
16 | );
17 | }
18 |
19 | export default TaskCard;
20 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/src/components/Task/TaskForm.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { FaPlus } from "react-icons/fa";
3 | import styles from "../../styles";
4 |
5 | function TaskForm({ onCreateTask }) {
6 | const [newTask, setNewTask] = useState({ title: "", description: "" });
7 |
8 | const handleSubmit = (e) => {
9 | e.preventDefault();
10 | onCreateTask(newTask);
11 | setNewTask({ title: "", description: "" });
12 | };
13 |
14 | return (
15 |
16 |
36 |
37 | );
38 | }
39 |
40 | export default TaskForm;
41 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/src/components/Task/TaskList.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import TaskCard from "./TaskCard";
3 |
4 | function TaskList({ tasks, isLoading, onDeleteTask }) {
5 | if (isLoading) {
6 | return Loading tasks...
;
7 | }
8 |
9 | return (
10 |
11 | {tasks.map((task) => (
12 |
13 | ))}
14 |
15 | );
16 | }
17 |
18 | export default TaskList;
19 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/NERDS/basic-template/basic-frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 |
6 | const root = ReactDOM.createRoot(document.getElementById("root"));
7 | root.render(
8 |
9 |
10 | ,
11 | );
12 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/README.md:
--------------------------------------------------------------------------------
1 | # Enhanced Template
2 |
3 | In this example you will build the TaskMaster application!
4 |
5 | 
6 |
7 | To execute this project please:
8 |
9 | 1. Open the [enhanced-backend](./enhanced-backend/README.md) folder with instructions to execute the backend locally.
10 | 2. Open the [enhanced-frontend](./enhanced-frontend/README.md) folder with instructions to execute the front end and run your web applicaation locally.
11 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-backend/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Esteban Serna
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-backend/documentation/enhanced-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/enhanced-template/enhanced-backend/documentation/enhanced-app.png
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-backend/documentation/enhanced-backend.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/enhanced-template/enhanced-backend/documentation/enhanced-backend.gif
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/README.md:
--------------------------------------------------------------------------------
1 | # Enhanced-frontend application ToDo list with priorities
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
10 | ## You can run your development server by running
11 |
12 | Before starting the backend, make sure you have already started the [backend](../enhanced-backend/README.md).
13 |
14 | `npm run dev` starts your development server and should open a sample todo application.
15 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import react from 'eslint-plugin-react'
4 | import reactHooks from 'eslint-plugin-react-hooks'
5 | import reactRefresh from 'eslint-plugin-react-refresh'
6 |
7 | export default [
8 | { ignores: ['dist'] },
9 | {
10 | files: ['**/*.{js,jsx}'],
11 | languageOptions: {
12 | ecmaVersion: 2020,
13 | globals: globals.browser,
14 | parserOptions: {
15 | ecmaVersion: 'latest',
16 | ecmaFeatures: { jsx: true },
17 | sourceType: 'module',
18 | },
19 | },
20 | settings: { react: { version: '18.3' } },
21 | plugins: {
22 | react,
23 | 'react-hooks': reactHooks,
24 | 'react-refresh': reactRefresh,
25 | },
26 | rules: {
27 | ...js.configs.recommended.rules,
28 | ...react.configs.recommended.rules,
29 | ...react.configs['jsx-runtime'].rules,
30 | ...reactHooks.configs.recommended.rules,
31 | 'react/jsx-no-target-blank': 'off',
32 | 'react-refresh/only-export-components': [
33 | 'warn',
34 | { allowConstantExport: true },
35 | ],
36 | },
37 | },
38 | ]
39 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "enhanced-frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "axios": "^1.7.7",
14 | "react": "^18.3.1",
15 | "react-dom": "^18.3.1",
16 | "react-icons": "^5.3.0"
17 | },
18 | "devDependencies": {
19 | "@eslint/js": "^9.9.0",
20 | "@types/react": "^18.3.3",
21 | "@types/react-dom": "^18.3.0",
22 | "@vitejs/plugin-react": "^4.3.1",
23 | "eslint": "^9.9.0",
24 | "eslint-plugin-react": "^7.35.0",
25 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
26 | "eslint-plugin-react-refresh": "^0.4.9",
27 | "globals": "^15.9.0",
28 | "vite": "^5.4.1"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/src/App.css:
--------------------------------------------------------------------------------
1 | #root {
2 | max-width: 1280px;
3 | margin: 0 auto;
4 | padding: 2rem;
5 | text-align: center;
6 | }
7 |
8 | .logo {
9 | height: 6em;
10 | padding: 1.5em;
11 | will-change: filter;
12 | transition: filter 300ms;
13 | }
14 | .logo:hover {
15 | filter: drop-shadow(0 0 2em #646cffaa);
16 | }
17 | .logo.react:hover {
18 | filter: drop-shadow(0 0 2em #61dafbaa);
19 | }
20 |
21 | @keyframes logo-spin {
22 | from {
23 | transform: rotate(0deg);
24 | }
25 | to {
26 | transform: rotate(360deg);
27 | }
28 | }
29 |
30 | @media (prefers-reduced-motion: no-preference) {
31 | a:nth-of-type(2) .logo {
32 | animation: logo-spin infinite 20s linear;
33 | }
34 | }
35 |
36 | .card {
37 | padding: 2em;
38 | }
39 |
40 | .read-the-docs {
41 | color: #888;
42 | }
43 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/src/components/Task/TaskList.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import TaskCard from "./TaskCard.jsx";
3 |
4 | function TaskList({ tasks, isLoading, onDeleteTask, onUpdateTask }) {
5 | if (isLoading) {
6 | return Loading tasks...
;
7 | }
8 |
9 | return (
10 |
11 | {tasks.map((task) => (
12 |
18 | ))}
19 |
20 | );
21 | }
22 |
23 | export default TaskList;
24 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react'
2 | import { createRoot } from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/examples/NERDS/enhanced-template/enhanced-frontend/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/README.md:
--------------------------------------------------------------------------------
1 | # Recipe Example
2 |
3 | This is the first full example in the NERDS stack, this examples fully uses SAM instead of ExpressJS for the backend. We will be working with a recipe sharing website! Where users can create recipes, collections, comment, share and subscribe to users, and at the end they could add elemnts to their shopping lists to buy the goods required to cook the recipe.
4 |
5 | **TODO**: This project is still work in progress and it needs additional documentation, we will be releasing the features by phases (which will be tracked in the release table below), the first one is an initial portion of the backend with only users and recipes interactions, and we will build all the way up to the full application, this approach is to make it easier to consume rather than a big bang!
6 |
7 | To execute this project please:
8 |
9 | 1. Open the [backend](./backend/README.md) folder with instructions to execute the backend locally.
10 | 2. Open the [frontend](./frontend/README.md) folder with instructions to execute the front end and run your web applicaation locally.
11 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/buildspec.yml:
--------------------------------------------------------------------------------
1 | version: 0.2
2 | phases:
3 | install:
4 | commands:
5 | # Install all dependencies (including dependencies for running tests)
6 | - npm install
7 | pre_build:
8 | commands:
9 | # Discover and run unit tests in the '__tests__' directory
10 | - npm run test
11 | # Remove all unit tests to reduce the size of the package that will be ultimately uploaded to Lambda
12 | - rm -rf ./__tests__
13 | # Remove all dependencies not needed for the Lambda deployment package (the packages from devDependencies in package.json)
14 | - npm prune --production
15 | build:
16 | commands:
17 | # Use AWS SAM to package the application by using AWS CloudFormation
18 | - aws cloudformation package --template template.yaml --s3-bucket $S3_BUCKET --output-template template-export.yml
19 | artifacts:
20 | type: zip
21 | files:
22 | - template-export.yml
23 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | dynamodb-local:
4 | command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
5 | image: "amazon/dynamodb-local:latest"
6 | container_name: dynamodb-local-recipe-backend
7 | ports:
8 | - "8000:8000"
9 | volumes:
10 | - "./docker/dynamodb:/home/dynamodblocal/data"
11 | working_dir: /home/dynamodblocal
12 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/docker/dynamodb/shared-local-instance.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/recipe-example/backend/docker/dynamodb/shared-local-instance.db
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/documentation/demo-api.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/recipe-example/backend/documentation/demo-api.gif
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/documentation/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/NERDS/recipe-example/backend/documentation/demo.gif
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/env.json:
--------------------------------------------------------------------------------
1 | {
2 | "Parameters": {
3 | "DYNAMODB_ENDPOINT": "http://dynamodb-local:8000"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/samconfig.toml:
--------------------------------------------------------------------------------
1 | # More information about the configuration file can be found here:
2 | # https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html
3 | version = 0.1
4 |
5 | [default]
6 | [default.global.parameters]
7 | stack_name = "sam-app"
8 |
9 | [default.build.parameters]
10 | cached = true
11 | parallel = true
12 |
13 | [default.validate.parameters]
14 | lint = true
15 |
16 | [default.deploy.parameters]
17 | capabilities = "CAPABILITY_IAM"
18 | confirm_changeset = true
19 | resolve_s3 = true
20 |
21 | [default.package.parameters]
22 | resolve_s3 = true
23 |
24 | [default.sync.parameters]
25 | watch = true
26 |
27 | [default.local_start_api.parameters]
28 | warm_containers = "EAGER"
29 |
30 | [default.local_start_lambda.parameters]
31 | warm_containers = "EAGER"
32 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "create-user",
3 | "version": "1.0.0",
4 | "type": "module",
5 | "dependencies": {
6 | "@aws-sdk/client-dynamodb": "^3.658.1",
7 | "@aws-sdk/util-dynamodb": "^3.658.1",
8 | "nanoid": "^5.0.7"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/src/recipes/get/index.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBDocumentClient, GetCommand } from "@aws-sdk/lib-dynamodb";
2 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
3 |
4 | const ENDPOINT_OVERRIDE = process.env.DYNAMODB_ENDPOINT || undefined;
5 | const clientConfig = ENDPOINT_OVERRIDE ? { endpoint: ENDPOINT_OVERRIDE } : {};
6 | const client = new DynamoDBClient(clientConfig);
7 | const ddbDocClient = DynamoDBDocumentClient.from(client);
8 |
9 | export const handler = async (event) => {
10 | try {
11 | const recipeId = event.pathParameters.recipeId;
12 |
13 | const { Item } = await ddbDocClient.send(
14 | new GetCommand({
15 | TableName: process.env.TABLE_NAME,
16 | Key: {
17 | PK: `RECIPE#${recipeId}`,
18 | SK: `RECIPE#${recipeId}`,
19 | },
20 | })
21 | );
22 |
23 | if (!Item) {
24 | return {
25 | statusCode: 404,
26 | body: JSON.stringify({ message: "Recipe not found" }),
27 | };
28 | }
29 |
30 | return {
31 | statusCode: 200,
32 | body: JSON.stringify(Item),
33 | };
34 | } catch (error) {
35 | console.error("Error getting recipe:", error);
36 | return {
37 | statusCode: 500,
38 | body: JSON.stringify({ message: "Error getting recipe" }),
39 | };
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/src/users/create/index.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";
2 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
3 | import { nanoid } from "nanoid";
4 |
5 | const ENDPOINT_OVERRIDE = process.env.DYNAMODB_ENDPOINT || undefined;
6 | const clientConfig = ENDPOINT_OVERRIDE ? { endpoint: ENDPOINT_OVERRIDE } : {};
7 | const client = new DynamoDBClient(clientConfig);
8 | const ddbDocClient = DynamoDBDocumentClient.from(client);
9 |
10 | export const handler = async (event) => {
11 | try {
12 | const user = JSON.parse(event.body);
13 | const userId = nanoid();
14 |
15 | const item = {
16 | PK: `USER#${userId}`,
17 | SK: `PROFILE#${userId}`,
18 | userId,
19 | ...user,
20 | createdAt: new Date().toISOString(),
21 | };
22 |
23 | console.log(process.env.TABLE_NAME);
24 | await ddbDocClient.send(
25 | new PutCommand({
26 | TableName: process.env.TABLE_NAME,
27 | Item: item,
28 | })
29 | );
30 |
31 | return {
32 | statusCode: 201,
33 | body: JSON.stringify({ message: "User created successfully", userId }),
34 | };
35 | } catch (error) {
36 | console.error("Error creating user:", error);
37 | return {
38 | statusCode: 500,
39 | body: JSON.stringify({
40 | message: "Error creating user",
41 | }),
42 | };
43 | }
44 | };
45 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/src/users/delete/index.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBDocumentClient, DeleteCommand } from "@aws-sdk/lib-dynamodb";
2 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
3 |
4 | const ENDPOINT_OVERRIDE = process.env.DYNAMODB_ENDPOINT || undefined;
5 | const clientConfig = ENDPOINT_OVERRIDE ? { endpoint: ENDPOINT_OVERRIDE } : {};
6 | const client = new DynamoDBClient(clientConfig);
7 | const ddbDocClient = DynamoDBDocumentClient.from(client);
8 |
9 | export const handler = async (event) => {
10 | try {
11 | const userId = event.pathParameters.userId;
12 |
13 | await ddbDocClient.send(
14 | new DeleteCommand({
15 | TableName: process.env.TABLE_NAME,
16 | Key: {
17 | PK: `USER#${userId}`,
18 | SK: `PROFILE#${userId}`,
19 | },
20 | })
21 | );
22 |
23 | return {
24 | statusCode: 200,
25 | body: JSON.stringify({ message: "User deleted successfully" }),
26 | };
27 | } catch (error) {
28 | console.error("Error deleting user:", error);
29 | return {
30 | statusCode: 500,
31 | body: JSON.stringify({ message: "Error deleting user" }),
32 | };
33 | }
34 | };
35 |
--------------------------------------------------------------------------------
/examples/NERDS/recipe-example/backend/src/users/get/index.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBDocumentClient, GetCommand } from "@aws-sdk/lib-dynamodb";
2 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
3 |
4 | const ENDPOINT_OVERRIDE = process.env.DYNAMODB_ENDPOINT || undefined;
5 | const clientConfig = ENDPOINT_OVERRIDE ? { endpoint: ENDPOINT_OVERRIDE } : {};
6 | const client = new DynamoDBClient(clientConfig);
7 | const ddbDocClient = DynamoDBDocumentClient.from(client);
8 |
9 | export const handler = async (event) => {
10 | try {
11 | const userId = event.pathParameters.userId;
12 |
13 | const { Item } = await ddbDocClient.send(
14 | new GetCommand({
15 | TableName: process.env.TABLE_NAME,
16 | Key: {
17 | PK: `USER#${userId}`,
18 | SK: `PROFILE#${userId}`,
19 | },
20 | })
21 | );
22 |
23 | if (!Item) {
24 | return {
25 | statusCode: 404,
26 | body: JSON.stringify({ message: "User not found" }),
27 | };
28 | }
29 |
30 | return {
31 | statusCode: 200,
32 | body: JSON.stringify(Item),
33 | };
34 | } catch (error) {
35 | console.error("Error getting user:", error);
36 | return {
37 | statusCode: 500,
38 | body: JSON.stringify({ message: "Error getting user" }),
39 | };
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/DotnetSamples.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/DotnetSamples.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30114.105
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotnetSamples", "DotnetSamples.csproj", "{9B0BC4F6-816F-46CC-93C8-996B52634A9B}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8B2150D8-880B-4A9B-ADE4-F9C375A7BBEF}"
9 | ProjectSection(SolutionItems) = preProject
10 | README.md = README.md
11 | EndProjectSection
12 | EndProject
13 | Global
14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
15 | Debug|Any CPU = Debug|Any CPU
16 | Release|Any CPU = Release|Any CPU
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {9B0BC4F6-816F-46CC-93C8-996B52634A9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {9B0BC4F6-816F-46CC-93C8-996B52634A9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {9B0BC4F6-816F-46CC-93C8-996B52634A9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {9B0BC4F6-816F-46CC-93C8-996B52634A9B}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(SolutionProperties) = preSolution
25 | HideSolutionNode = FALSE
26 | EndGlobalSection
27 | GlobalSection(ExtensibilityGlobals) = postSolution
28 | SolutionGuid = {2DC8A6B8-E3AD-48C3-99B8-8181326A6F07}
29 | EndGlobalSection
30 | EndGlobal
31 |
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/Models/CustomerOrder.cs:
--------------------------------------------------------------------------------
1 | namespace DotnetSamples.Models
2 | {
3 | public class CustomerOrder
4 | {
5 | public string PK { get; set; }
6 | public string SK { get; set; }
7 | public string CustomerName { get; set; }
8 | public string OrderName { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/WorkingWithItems/GetItem.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | using Amazon;
6 | using Amazon.DynamoDBv2;
7 | using Amazon.DynamoDBv2.Model;
8 |
9 | namespace DotnetSamples.WorkingWithItems
10 | {
11 | class GetItem
12 | {
13 | public static async Task ServiceClientExampleAsync()
14 | {
15 | try
16 | {
17 | var client = new AmazonDynamoDBClient(RegionEndpoint.USWest2);
18 |
19 | var request = new GetItemRequest
20 | {
21 | TableName = "RetailDatabase",
22 | Key = new Dictionary
23 | {
24 | {"pk", new AttributeValue {S = "jim.bob@somewhere.com"} },
25 | {"sk", new AttributeValue {S = "metadata"} }
26 | }
27 | };
28 |
29 | var response = await client.GetItemAsync(request);
30 | Console.WriteLine($"Item retrieved with {response.Item.Count} attributes.");
31 | }
32 | catch(Exception e)
33 | {
34 | Console.Error.WriteLine(e.Message);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/WorkingWithQueries/QueryCount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using Amazon;
5 | using Amazon.DynamoDBv2;
6 | using Amazon.DynamoDBv2.Model;
7 |
8 | namespace DotnetSamples.WorkingWithQueries
9 | {
10 | public class QueryCount
11 | {
12 | public static async Task CountDbClientExampleAsync()
13 | {
14 | try
15 | {
16 | var client = new AmazonDynamoDBClient(RegionEndpoint.USEast1);
17 | var request = new QueryRequest
18 | {
19 | TableName="MyTableName",
20 | KeyConditionExpression="PK = :pk AND begins_with(SK, :sk)",
21 | ExpressionAttributeValues = new Dictionary
22 | {
23 | { ":pk", new AttributeValue { S="Customer1" } },
24 | { ":sk", new AttributeValue { S="ORDER|"} }
25 | }
26 | };
27 |
28 | var response = await client.QueryAsync(request);
29 |
30 | Console.WriteLine($"The query has scanned {response.ScannedCount} items and returned ${response.Count} items in total");
31 | }
32 | catch(Exception ex)
33 | {
34 | Console.Error.WriteLine(ex.Message);
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/WorkingWithQueries/QueryFilterExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using Amazon;
5 | using Amazon.DynamoDBv2;
6 | using Amazon.DynamoDBv2.Model;
7 |
8 | namespace DotnetSamples.WorkingWithQueries
9 | {
10 | public class QueryFilterExpression
11 | {
12 | public static async Task FilterExpressionDbClientExampleAsync()
13 | {
14 | try
15 | {
16 | var client = new AmazonDynamoDBClient(RegionEndpoint.USEast1);
17 | var request = new QueryRequest
18 | {
19 | TableName="MyTableName",
20 | KeyConditionExpression="PK = :pk",
21 | FilterExpression="CustomerName = :cn",
22 | ExpressionAttributeValues = new Dictionary
23 | {
24 | { ":pk", new AttributeValue { S="Customer1" } },
25 | { ":cn", new AttributeValue { S="John Smith" }}
26 | },
27 | };
28 |
29 | var response = await client.QueryAsync(request);
30 |
31 | Console.WriteLine("Success");
32 | }
33 | catch(Exception ex)
34 | {
35 | Console.WriteLine(ex.Message);
36 | }
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/examples/SDK/dotnet/sdk_v2/WorkingWithQueries/QueryProjectionExpression.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 | using Amazon;
5 | using Amazon.DynamoDBv2;
6 | using Amazon.DynamoDBv2.Model;
7 |
8 | namespace DotnetSamples.WorkingWithQueries
9 | {
10 | public class QueryProjectionExpression
11 | {
12 | public async Task QueryProjectionExpressionDbClientExmaple()
13 | {
14 | try
15 | {
16 | var client = new AmazonDynamoDBClient(RegionEndpoint.USEast1);
17 | var request = new QueryRequest
18 | {
19 | TableName="MyTableName",
20 | ProjectionExpression="CustomerId, #cn",
21 | ExpressionAttributeNames= new Dictionary
22 | {
23 | { "#cn", "CustomerName" }
24 | },
25 | KeyConditionExpression="PK = :pk",
26 | ExpressionAttributeValues = new Dictionary
27 | {
28 | { ":pk", new AttributeValue { S="Customer1" } },
29 | },
30 | };
31 |
32 | var response = await client.QueryAsync(request);
33 |
34 | Console.WriteLine("Success");
35 | }
36 | catch(Exception ex)
37 | {
38 | Console.WriteLine(ex.Message);
39 | }
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/examples/SDK/golang/README.md:
--------------------------------------------------------------------------------
1 | # 🐹 Golang SDK examples for Amazon DynamoDB
2 |
3 | This section contains Golang code for examples and common tasks with Amazon DynamoDB.
4 |
5 | ## ⚠️ Deprecation Warning: Golang SDK v1 Examples ⚠️
6 |
7 | With the announce of [EOS for the Golang SDK v1](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/), all the v1 examples in this repository are in maintenance mode as well. If you want to collaborate migrating the current examples to v2 you are encouraged to send a PR.
8 |
9 | ## 🛠️ Working with Items
10 |
11 | Explore a wide range of operations for managing individual items in your DynamoDB tables, from batch processing to conditional updates.
12 |
13 | [View the Item examples »](./sdk_v1/WorkingWithItems/)
14 |
15 | ## 🗃️ Working with Tables
16 |
17 | From creating and deleting tables to managing global tables and auto-scaling, this section has you covered for all your table management needs.
18 |
19 | [Discover the Table examples »](./sdk_v1/WorkingWithTables)
20 |
21 | # Detailed list of supported operations
22 |
23 |
24 |
25 | You can consult the list of all the supported operations in this repo in the [Operations](./Operations.md) page.
26 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithItems/deleteItem.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
8 |
9 | "fmt"
10 | "os"
11 | )
12 |
13 | // Item struct to hold keys
14 | type Item struct {
15 | Pk string `json:"pk"`
16 | Sk string `json:"sk"`
17 | }
18 |
19 | func main() {
20 |
21 | // Create Session
22 | sess, err := session.NewSession(&aws.Config{
23 | Region: aws.String("eu-west-1")},
24 | )
25 |
26 | // Create DynamoDB client
27 | svc := dynamodb.New(sess)
28 |
29 | // Keys for item
30 | item := Item{
31 | Pk: "jose.schneller@somewhere.com",
32 | Sk: "metadata",
33 | }
34 |
35 | // Marshal
36 | av, err := dynamodbattribute.MarshalMap(item)
37 | if err != nil {
38 | fmt.Println("Got error marshalling map:")
39 | fmt.Println(err.Error())
40 | os.Exit(1)
41 | }
42 |
43 | // Delete Item
44 | input := &dynamodb.DeleteItemInput{
45 | TableName: aws.String("RetailDatabase"),
46 | Key: av,
47 | }
48 |
49 | _, err = svc.DeleteItem(input)
50 | if err != nil {
51 | fmt.Println("Got error calling DeleteItem")
52 | fmt.Println(err.Error())
53 | return
54 | }
55 |
56 | fmt.Println("Deleted Item")
57 | }
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/addGlobalTableRegion/addGlobalTableRegion.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var table = "Music"
11 | var awsRegion = "ap-northeast-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func updateTable() error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 |
28 | replicaUpdates := []*dynamodb.ReplicaUpdate{
29 | {
30 | Create: &dynamodb.CreateReplicaAction{
31 | RegionName: aws.String(awsRegion),
32 | },
33 | },
34 | }
35 |
36 | _, err := dynamoDBClient.UpdateGlobalTable(&dynamodb.UpdateGlobalTableInput{
37 | GlobalTableName: &table,
38 | ReplicaUpdates: replicaUpdates,
39 | })
40 |
41 | if err != nil {
42 | fmt.Println("Got error updating Global Table.", err)
43 | return err
44 | }
45 |
46 | return nil
47 | }
48 |
49 | func main() {
50 | fmt.Println("Creating Global Table ...")
51 | updateTable()
52 | fmt.Println("Finished ...")
53 | }
54 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/deleteGlobalTableRegion/deleteGlobalTableRegion.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var table = "Music"
11 | var awsRegion = "ap-northeast-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func updateTable() error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 |
28 | replicaUpdates := []*dynamodb.ReplicaUpdate{
29 | {
30 | Delete: &dynamodb.DeleteReplicaAction{
31 | RegionName: aws.String(awsRegion),
32 | },
33 | },
34 | }
35 |
36 | _, err := dynamoDBClient.UpdateGlobalTable(&dynamodb.UpdateGlobalTableInput{
37 | GlobalTableName: &table,
38 | ReplicaUpdates: replicaUpdates,
39 | })
40 |
41 | if err != nil {
42 | fmt.Println("Got error updating Global Table.", err)
43 | return err
44 | }
45 |
46 | return nil
47 | }
48 |
49 | func main() {
50 | fmt.Println("Creating Global Table ...")
51 | updateTable()
52 | fmt.Println("Finished ...")
53 | }
54 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/deleteTable/deleteTable.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var tableName = "Music"
11 | var awsRegion = "us-west-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func deleteTable() error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 |
28 | _, err := dynamoDBClient.DeleteTable(&dynamodb.DeleteTableInput{
29 | TableName: aws.String(tableName),
30 | })
31 |
32 | if err != nil {
33 | fmt.Println("Error deleting table", err)
34 | return err
35 | }
36 |
37 | return nil
38 | }
39 |
40 | func main() {
41 | fmt.Println("Enabling streams in table ...")
42 | deleteTable()
43 | fmt.Println("Finished ...")
44 | }
45 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/describeLimits/describeLimits.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var awsRegion = "us-west-2"
11 |
12 | func getSession() (*session.Session) {
13 | sess := session.Must(session.NewSessionWithOptions(session.Options{
14 | SharedConfigState: session.SharedConfigEnable,
15 | // Provide SDK Config options, such as Region and Endpoint
16 | Config: aws.Config{
17 | Region: aws.String(awsRegion),
18 | },
19 | }))
20 |
21 | return sess
22 | }
23 |
24 | func describeLimits() error {
25 | dynamoDBClient := dynamodb.New(getSession())
26 | response, err := dynamoDBClient.DescribeLimits(&dynamodb.DescribeLimitsInput{})
27 |
28 | if err != nil {
29 | return err
30 | }
31 |
32 | fmt.Println("Table Limits ...", response)
33 | return nil
34 | }
35 |
36 | func main() {
37 | fmt.Println("Describing DynamoDB Limits ...")
38 | describeLimits()
39 | fmt.Println("Finished ...")
40 | }
41 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/describeTable/describeTable.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var tableName = "Music"
11 | var awsRegion = "us-west-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func describeTable(tableName string) error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 | response, err := dynamoDBClient.DescribeTable(&dynamodb.DescribeTableInput{
28 | TableName: aws.String(tableName),
29 | })
30 |
31 | if err != nil {
32 | return err
33 | }
34 |
35 | fmt.Println(response)
36 | return nil
37 | }
38 |
39 | func main() {
40 | fmt.Println("Describing Table ...")
41 | describeTable(tableName)
42 | fmt.Println("Finished ...")
43 | }
44 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/disableStreams/disableStreams.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var tableName = "Music"
11 | var awsRegion = "us-west-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func enableStreams() error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 |
28 | _, err := dynamoDBClient.UpdateTable(&dynamodb.UpdateTableInput{
29 | StreamSpecification: &dynamodb.StreamSpecification{
30 | StreamEnabled: aws.Bool(false),
31 | },
32 | TableName: aws.String(tableName),
33 | })
34 |
35 | if err != nil {
36 | fmt.Println("Error disabling streams", err)
37 | return err
38 | }
39 |
40 | return nil
41 | }
42 |
43 | func main() {
44 | fmt.Println("Diasbling streams in table ...")
45 | enableStreams()
46 | fmt.Println("Finished ...")
47 | }
48 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/enableStreams/enableStreams.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var tableName = "Music"
11 | var awsRegion = "us-west-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func enableStreams() error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 |
28 | _, err := dynamoDBClient.UpdateTable(&dynamodb.UpdateTableInput{
29 | StreamSpecification: &dynamodb.StreamSpecification{
30 | StreamEnabled: aws.Bool(true),
31 | //'NEW_IMAGE'|'OLD_IMAGE'|'NEW_AND_OLD_IMAGES'|'KEYS_ONLY'
32 | StreamViewType: aws.String("NEW_AND_OLD_IMAGES"),
33 | },
34 | TableName: aws.String(tableName),
35 | })
36 |
37 | if err != nil {
38 | fmt.Println("Error enabling streams", err)
39 | return err
40 | }
41 |
42 | return nil
43 | }
44 |
45 | func main() {
46 | fmt.Println("Enabling streams in table ...")
47 | enableStreams()
48 | fmt.Println("Finished ...")
49 | }
50 |
--------------------------------------------------------------------------------
/examples/SDK/golang/sdk_v1/WorkingWithTables/listTables/listTables.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/aws/aws-sdk-go/aws"
5 | "github.com/aws/aws-sdk-go/aws/session"
6 | "github.com/aws/aws-sdk-go/service/dynamodb"
7 | "fmt"
8 | )
9 |
10 | var tableName = "Music"
11 | var awsRegion = "us-west-2"
12 |
13 | func getSession() (*session.Session) {
14 | sess := session.Must(session.NewSessionWithOptions(session.Options{
15 | SharedConfigState: session.SharedConfigEnable,
16 | // Provide SDK Config options, such as Region and Endpoint
17 | Config: aws.Config{
18 | Region: aws.String(awsRegion),
19 | },
20 | }))
21 |
22 | return sess
23 | }
24 |
25 | func listTables(tableName string) error {
26 | dynamoDBClient := dynamodb.New(getSession())
27 | response, err := dynamoDBClient.ListTables(&dynamodb.ListTablesInput{})
28 |
29 | if err != nil {
30 | return err
31 | }
32 |
33 | fmt.Println(response)
34 | return nil
35 | }
36 |
37 | func main() {
38 | fmt.Println("Listing Tables ...")
39 | listTables(tableName)
40 | fmt.Println("Finished ...")
41 | }
42 |
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/AddProvisionedCapacity.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 | import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
5 | import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest;
6 |
7 | public class AddProvisionedCapacity {
8 |
9 | public static void main(String[] args) {
10 | // Create Client
11 | DynamoDbClient client = DynamoDbClient.builder().build();
12 | // Update the existing table
13 | client.updateTable(UpdateTableRequest.builder()
14 | .provisionedThroughput(ProvisionedThroughput.builder()
15 | .readCapacityUnits(10L)
16 | .writeCapacityUnits(10L)
17 | .build())
18 | .tableName("RetailDatabase")
19 | .build());
20 | }
21 | }
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/DescribeLimits.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 |
5 | public class DescribeLimits {
6 |
7 | public static void main(String[] args) {
8 | // Create Client
9 | DynamoDbClient client = DynamoDbClient.builder().build();
10 | System.out.println(client.describeLimits());
11 | }
12 | }
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/DescribeTable.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 | import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest;
5 |
6 | public class DescribeTable {
7 |
8 | public static void main(String[] args) {
9 | // Create Client
10 | DynamoDbClient client = DynamoDbClient.builder().build();
11 | System.out.println(client.describeTable(DescribeTableRequest.builder().tableName("RetailDatabase").build()));
12 | }
13 | }
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/ListTables.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 |
5 | public class ListTables {
6 |
7 | public static void main(String[] args) {
8 | // Create Client
9 | DynamoDbClient client = DynamoDbClient.builder().build();
10 | System.out.println(client.listTables());
11 | }
12 | }
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/TableChangeToOnDemand.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 | import software.amazon.awssdk.services.dynamodb.model.BillingMode;
5 | import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest;
6 |
7 | public class TableChangeToOnDemand {
8 |
9 | public static void main(String[] args) {
10 | // Create Client
11 | DynamoDbClient client = DynamoDbClient.builder().build();
12 | client.updateTable(UpdateTableRequest.builder()
13 | .billingMode(BillingMode.PAY_PER_REQUEST)
14 | .tableName("RetailDatabase")
15 | .build());
16 | }
17 | }
--------------------------------------------------------------------------------
/examples/SDK/java/sdk_v1/control_plane/WorkingWithTables/TableChangeToOnProvisioned.java:
--------------------------------------------------------------------------------
1 | package com.example.myapp;
2 |
3 | import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
4 | import software.amazon.awssdk.services.dynamodb.model.BillingMode;
5 | import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest;
6 |
7 | public class TableChangeToOnProvisioned {
8 |
9 | public static void main(String[] args) {
10 | // Create Client
11 | DynamoDbClient client = DynamoDbClient.builder().build();
12 | client.updateTable(UpdateTableRequest.builder()
13 | .billingMode(BillingMode.PROVISIONED)
14 | .tableName("RetailDatabase")
15 | .build());
16 | }
17 | }
--------------------------------------------------------------------------------
/examples/SDK/kotlin/control_plane/WorkingWithTables/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/control_plane/WorkingWithTables/.todo
--------------------------------------------------------------------------------
/examples/SDK/kotlin/data_plane/WorkingWithIndexes/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/data_plane/WorkingWithIndexes/.todo
--------------------------------------------------------------------------------
/examples/SDK/kotlin/data_plane/WorkingWithItems/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/data_plane/WorkingWithItems/.todo
--------------------------------------------------------------------------------
/examples/SDK/kotlin/data_plane/WorkingWithQueries/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/data_plane/WorkingWithQueries/.todo
--------------------------------------------------------------------------------
/examples/SDK/kotlin/data_plane/WorkingWithScans/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/data_plane/WorkingWithScans/.todo
--------------------------------------------------------------------------------
/examples/SDK/kotlin/data_plane/WorkingWithStreams/.todo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/examples/SDK/kotlin/data_plane/WorkingWithStreams/.todo
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithBackups/CreateOn-DemandBackup.js:
--------------------------------------------------------------------------------
1 | // A simple script to create an on-demand backup of a DynamoDB table.
2 |
3 | const { DynamoDBClient, CreateBackupCommand } = require('@aws-sdk/client-dynamodb'); // ES Modules import
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music";
7 | const BackupName = TableName + "-backup-" + Date.now(); //add an epoch time to the end of the name
8 |
9 | async function createBackup() {
10 | const client = new DynamoDBClient({ region: REGION });
11 | try {
12 | return await client.send(
13 | new CreateBackupCommand({
14 | BackupName: BackupName,
15 | TableName: TableName,
16 | },)
17 | );
18 | } catch (err) {
19 | console.error(err);
20 | }
21 | }
22 |
23 | createBackup()
24 | .then((data) => console.log(data))
25 | .catch((error) => console.log("An error occurred while creating the on-demand backup:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithBackups/DeleteBackup.js:
--------------------------------------------------------------------------------
1 | // A simple script to delete an on-demand backup of a DynamoDB table.
2 |
3 | const { DynamoDBClient, DeleteBackupCommand } = require('@aws-sdk/client-dynamodb'); // ES Modules import
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "";
7 | const AccountNumber = "";
8 | const BackupID = "";
9 | const BackupArn = "arn:aws:dynamodb:" + REGION + ":" + AccountNumber + ":table/"+ TableName + "/backup/" + BackupID;
10 |
11 | async function deleteBackup() {
12 | const client = new DynamoDBClient({ region: REGION });
13 | try {
14 | return await client.send(
15 | new DeleteBackupCommand({
16 | BackupArn: BackupArn,
17 | },)
18 | );
19 | } catch (err) {
20 | console.error(err);
21 | }
22 | }
23 |
24 | deleteBackup()
25 | .then((data) => console.log(data))
26 | .catch((error) => console.log("An error occurred while deleting a backup:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithBackups/DescribeBackup.js:
--------------------------------------------------------------------------------
1 | // A simple script to describe an on-demand backup of a DynamoDB table.
2 |
3 | const { DynamoDBClient, DescribeBackupCommand } = require('@aws-sdk/client-dynamodb'); // ES Modules import
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "";
7 | const AccountNumber = "";
8 | const BackupID = "";
9 |
10 | const BackupArn = "arn:aws:dynamodb:" + REGION + ":" + AccountNumber + ":table/"+ TableName + "/backup/" + BackupID;
11 |
12 | async function DescribeBackup() {
13 | const client = new DynamoDBClient({ region: REGION });
14 | try {
15 | return await client.send(
16 | new DescribeBackupCommand({
17 | BackupArn: BackupArn,
18 | },)
19 | );
20 | } catch (err) {
21 | console.error(err);
22 | }
23 | }
24 |
25 | DescribeBackup()
26 | .then((data) => console.log(data))
27 | .catch((error) => console.log("An error occurred while describing a backup:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithIndexes/DeleteIndex.js:
--------------------------------------------------------------------------------
1 | // A simple example to delete a global secondary index (GSI) on an existing table DynamoDB table.
2 |
3 | const { DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb'); // ES Modules import
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music";
7 | const IndexName = "SongTitle-Artist-index";
8 |
9 | async function deleteIndex() {
10 | const client = new DynamoDBClient({ region: REGION });
11 | try {
12 | return await client.send(
13 | new UpdateTableCommand({
14 | TableName: TableName,
15 | GlobalSecondaryIndexUpdates: [ {
16 | Delete: {
17 | IndexName: IndexName,
18 | }
19 | }],
20 | },)
21 | );
22 | } catch (err) {
23 | console.error(err);
24 | }
25 | }
26 |
27 | deleteIndex()
28 | .then((data) => console.log(data))
29 | .catch((error) => console.log("An error occurred while creating the index:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithIndexes/UpdateIndexProvisionedCapacity.js:
--------------------------------------------------------------------------------
1 | // A simple example to update the provisioned capacity of a global secondary index (GSI) on an existing table DynamoDB table.
2 | // Note: this specific example does not alter a GSI's auto-scaling settings or Contributor Insights settings. That is a different script.
3 |
4 | const { DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb'); // ES Modules import
5 |
6 | const REGION = "us-west-2";
7 | const TableName = "Music";
8 | const IndexName = "SongTitle-Artist-index";
9 |
10 | async function updateIndex() {
11 | const client = new DynamoDBClient({ region: REGION });
12 | try {
13 | return await client.send(
14 | new UpdateTableCommand({
15 | TableName: TableName,
16 | GlobalSecondaryIndexUpdates: [ {
17 | Update: {
18 | IndexName: IndexName,
19 | ProvisionedThroughput: {
20 | ReadCapacityUnits: 25,
21 | WriteCapacityUnits: 25,
22 | },
23 | }
24 | }],
25 | },)
26 | );
27 | } catch (err) {
28 | console.error(err);
29 | }
30 | }
31 |
32 | updateIndex()
33 | .then((data) => console.log(data.TableDescription))
34 | .catch((error) => console.log("An error occurred while updating the index capacity:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/add-global-table-region.js:
--------------------------------------------------------------------------------
1 | //const AWS = require("aws-sdk");
2 |
3 | //const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 | const { DynamoDBClient, UpdateTableCommand, UpdateGlobalTableCommand } = require('@aws-sdk/client-dynamodb');
5 |
6 | const REGION = "us-west-2";
7 | //const TABLENAME = "RetailDatabase";
8 |
9 | async function addGlobalTableRegion() {
10 | const params = {
11 | TableName: "RetailDatabase",
12 | ReplicaUpdates: [
13 | {
14 | Create: {
15 | RegionName: "ap-northeast-2",
16 | },
17 | },
18 | ],
19 | };
20 |
21 | const dbclient = new DynamoDBClient({ region: REGION });
22 |
23 | return await dbclient.send( new UpdateTableCommand(params));
24 |
25 | }
26 |
27 | addGlobalTableRegion()
28 | .then((data) => console.log(JSON.stringify(data, null, 2)))
29 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
30 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/add_provisioned_capacity.js:
--------------------------------------------------------------------------------
1 | // A simple script to add provisioned capacity to an existing table.
2 |
3 | const {DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb');
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music"; //Change this to your table name
7 |
8 | const dbclient = new DynamoDBClient({ region: REGION });
9 |
10 | async function addCapacity() {
11 | const params = {
12 | TableName: TableName,
13 | ProvisionedThroughput: {
14 | ReadCapacityUnits: 10,
15 | WriteCapacityUnits: 5,
16 | },
17 | };
18 | return await dbclient.send( new UpdateTableCommand(params));
19 | // await waitForTableExists({ maxWaitTime: 20, maxDelay: 5, minDelay: 1 }, { TableName: TableName } );
20 | // this code is commented out as there is something wrong with the waiters in v3. Once that is fixed, this code will be updated.
21 | }
22 |
23 | addCapacity()
24 | .then((data) => console.log(data))
25 | .catch((error) => console.log("An error occurred while updating the table:" + ' ' + error.message ));
26 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/create-global-table.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 |
5 | const tableName = "Music";
6 |
7 | // Note: This method only applies to Version 2017.11.29 of global tables.
8 | // Before using this method, you must create the table in both regions.
9 | async function createGlobalTable() {
10 | const params = {
11 | GlobalTableName: tableName,
12 | ReplicationGroup: [
13 | { RegionName: "us-west-2" },
14 | { RegionName: "ap-northeast-2" },
15 | ],
16 | };
17 |
18 | const response = await dynamodb.createGlobalTable(params).promise();
19 | return response;
20 | }
21 |
22 | createGlobalTable()
23 | .then((data) => console.log(JSON.stringify(data, null, 2)))
24 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
25 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/create_table_on_demand.js:
--------------------------------------------------------------------------------
1 | // A simple script to create an on-demand capacity mode DynamoDB table.
2 |
3 | const { DynamoDBClient, CreateTableCommand } = require('@aws-sdk/client-dynamodb');
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music";
7 |
8 | const dbclient = new DynamoDBClient({ region: REGION });
9 |
10 | async function createTable() {
11 | const params = {
12 | AttributeDefinitions: [
13 | {
14 | AttributeName: "Artist",
15 | AttributeType: "S",
16 | },
17 | {
18 | AttributeName: "SongTitle",
19 | AttributeType: "S",
20 | },
21 | ],
22 | KeySchema: [
23 | {
24 | AttributeName: "Artist",
25 | KeyType: "HASH", // Partition key
26 | },
27 | {
28 | AttributeName: "SongTitle",
29 | KeyType: "RANGE", // Sort key
30 | },
31 | ],
32 | BillingMode: "PAY_PER_REQUEST",
33 | TableName: TableName, // Substitute your table name for "Music"
34 | };
35 | return await dbclient.send( new CreateTableCommand(params));
36 | }
37 |
38 | createTable()
39 | .then((data) => console.log(data))
40 | .catch((error) => console.log("An error occurred while creating the table:" + ' ' + error.message ));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/delete-global-table-region.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 |
5 | const tableName = "Music";
6 |
7 | async function deleteGlobalTableRegion() {
8 | const params = {
9 | TableName: tableName,
10 | ReplicaUpdates: [
11 | {
12 | Delete: {
13 | RegionName: "ap-northeast-2",
14 | },
15 | },
16 | ],
17 | };
18 |
19 | const response = await dynamodb.updateTable(params).promise();
20 | return response;
21 | }
22 |
23 | deleteGlobalTableRegion()
24 | .then((data) => console.log(JSON.stringify(data, null, 2)))
25 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
26 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/delete_table.js:
--------------------------------------------------------------------------------
1 | // A simple script to delete a DynamoDB table.
2 |
3 | // Be advised that when you delete a table, it does not delete auto-scaling info (e.g. scalable
4 | // targets, scaling policies) or CloudWatch alarms. This must be done in seperate calls.
5 |
6 | const { DynamoDBClient, DeleteTableCommand } = require('@aws-sdk/client-dynamodb');
7 |
8 | const REGION = "us-west-2";
9 | const TableName = "Music";
10 |
11 | const dbclient = new DynamoDBClient({ region: REGION });
12 |
13 | async function deleteTable() {
14 | const params = {
15 | TableName: TableName,
16 | };
17 | return await dbclient.send( new DeleteTableCommand(params));
18 | }
19 |
20 | deleteTable()
21 | .then((data) => console.log(data))
22 | .catch((error) => console.log("An error occurred while deleting the table:" + ' ' + error.message ));
23 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/describe-global-table-and-global-table-settings.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 |
5 | const tableName = "Music";
6 |
7 | // Note: This method only applies to Version 2017.11.29 of global tables.
8 | async function describeGlobalTable() {
9 | const params = {
10 | GlobalTableName: tableName,
11 | };
12 |
13 | const response = await dynamodb.describeGlobalTable(params).promise();
14 | return response;
15 | }
16 |
17 | // Note: This method only applies to Version 2017.11.29 of global tables.
18 | async function describeGlobalTableSettings() {
19 | const params = {
20 | GlobalTableName: tableName,
21 | };
22 |
23 | const response = await dynamodb.describeGlobalTableSettings(params).promise();
24 | return response;
25 | }
26 |
27 | async function describeAll() {
28 | const information = await describeGlobalTable();
29 | console.log(JSON.stringify(information, null, 2));
30 |
31 | const settings = await describeGlobalTableSettings();
32 | console.log(JSON.stringify(settings, null, 2));
33 | }
34 |
35 | describeAll().catch((error) => console.error(JSON.stringify(error, null, 2)));
36 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/describe_limits.js:
--------------------------------------------------------------------------------
1 | // A simple script to describe the quotas on an existing table.
2 |
3 | const {DynamoDBClient, DescribeLimitsCommand } = require('@aws-sdk/client-dynamodb');
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music"; //Change this to your table name
7 |
8 | const dbclient = new DynamoDBClient({ region: REGION });
9 |
10 | async function describeLimits() {
11 | const params = {
12 | TableName: TableName,
13 | };
14 | return await dbclient.send( new DescribeLimitsCommand(params));
15 | }
16 |
17 | describeLimits()
18 | .then((data) => console.log(data))
19 | .catch((error) => console.log("An error occurred while get the table limits:" + ' ' + error.message ));
20 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/describe_table.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 |
5 | const describeTable = async () => {
6 | const response = await dynamodb
7 | .describeTable({ TableName: "Music" }) // Substitute your table name for "Music"
8 | .promise();
9 |
10 | //console.log(JSON.stringify(response, null, 2));
11 | let test = JSON.stringify(response.Table.StreamSpecification.StreamEnabled, null, 2)
12 | console.log(test)
13 | };
14 |
15 | describeTable().catch((error) => console.error(JSON.stringify(error, null, 2)));
16 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/disable_streams.js:
--------------------------------------------------------------------------------
1 | // This code disables DynamoDB Streams on the target table.
2 |
3 | const {DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb');
4 |
5 | const REGION = "us-west-2";
6 | const TableName = "Music";
7 |
8 | const dbclient = new DynamoDBClient({ region: REGION });
9 |
10 | async function disableStreams() {
11 | const params = {
12 | TableName: TableName,
13 | StreamSpecification: {
14 | StreamEnabled: false,
15 | },
16 | };
17 | return await dbclient.send( new UpdateTableCommand(params));
18 | }
19 |
20 | disableStreams()
21 | .then((data) => console.log(data))
22 | .catch((error) => console.log("An error occurred while disabling streams:" + ' ' + error.message ));
23 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/enable_streams.js:
--------------------------------------------------------------------------------
1 | // The StreamViewType can be any of the following values 'NEW_IMAGE'|'OLD_IMAGE'|'NEW_AND_OLD_IMAGES'|'KEYS_ONLY',
2 | // but if you want to use Global Tables, it must be set to NEW_AND_OLD_IMAGES.
3 |
4 | const {DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb');
5 |
6 | const REGION = "us-west-2";
7 | const TableName = "Music";
8 |
9 | const dbclient = new DynamoDBClient({ region: REGION });
10 |
11 | async function enableStreams() {
12 | const params = {
13 | TableName: TableName,
14 | StreamSpecification: {
15 | StreamEnabled: true,
16 | StreamViewType: "NEW_AND_OLD_IMAGES",
17 | },
18 | };
19 | return await dbclient.send( new UpdateTableCommand(params));
20 | // await waitForTableExists({ maxWaitTime: 20, maxDelay: 5, minDelay: 1 }, { TableName: TableName } );
21 | // this code is commented out as there is something wrong with the waiters in v3. Once that is fixed, this code will be updated.
22 | }
23 |
24 | enableStreams()
25 | .then((data) => console.log(data))
26 | .catch((error) => console.log("An error occurred while enabling streams:" + ' ' + error.message ));
27 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/export_table_s3.js:
--------------------------------------------------------------------------------
1 | // This is simple example to export dynamodb table to S3 bucket.
2 |
3 | const {
4 | DynamoDBClient,
5 | ExportTableToPointInTimeCommand,
6 | } = require("@aws-sdk/client-dynamodb");
7 |
8 | // S3 bucket should be created before hand, and best practice is to enable encryption and version
9 | // Make sure PITR is enabled in DYNAMODB table
10 | // Make sure to replace with proper bucket name and account id
11 | const s3_bucket_name = "YOUR S3 Bucket";
12 | const table_arn = "arn:aws:dynamodb:us-east-1:YOUR ACCOUNT ID:table/Music";
13 |
14 | async function exportTables() {
15 | const client = new DynamoDBClient({ region: "us-east-1" });
16 | try {
17 | return await client.send(
18 | new ExportTableToPointInTimeCommand({
19 | S3Bucket: s3_bucket_name,
20 | TableArn: table_arn,
21 | ExportFormat: "DYNAMODB_JSON",
22 | ExportTime: new Date("Thu Dec 16 2021 16:46:00 GMT-0600 (CST)"),
23 | S3Prefix: "DYNAMODB-Export",
24 | S3SseAlgorithm: "AES256",
25 | })
26 | );
27 | } catch (err) {
28 | console.error(err);
29 | }
30 | }
31 |
32 | exportTables()
33 | .then((data) =>
34 | console.log("ExportTables succeeded:", JSON.stringify(data, null, 2))
35 | )
36 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
37 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/list_tables.js:
--------------------------------------------------------------------------------
1 | const { DynamoDBClient, ListTablesCommand } = require("@aws-sdk/client-dynamodb");
2 |
3 | (async () => {
4 | const client = new DynamoDBClient({ region: "us-west-2" });
5 | const command = new ListTablesCommand({});
6 | try {
7 | const results = await client.send(command);
8 | console.log(results.TableNames.join("\n"));
9 | } catch (err) {
10 | console.error(err);
11 | }
12 | })();
13 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/table_change_to_on_demand.js:
--------------------------------------------------------------------------------
1 | /*
2 | A simple script to switch a table to on-demand capacity mode.
3 |
4 | Note: Changing a table to on-demand mode may take a few minutes if DynamoDB
5 | must create partitions in the background to meet the minimum for on-demand
6 | capacity mode.
7 | */
8 |
9 | const { DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb');
10 |
11 | const REGION = "us-west-2"; // Replace with your target region
12 | const TableName = "Music"; // Replace with your table name.
13 |
14 | const dbclient = new DynamoDBClient({ region: REGION });
15 |
16 | async function updateTable() {
17 | const params = {
18 | BillingMode: "PAY_PER_REQUEST",
19 | TableName: TableName,
20 | };
21 | return await dbclient.send( new UpdateTableCommand(params));
22 | // Add code to wait for table update to complete before returning.
23 | }
24 |
25 | updateTable()
26 | .then((data) => console.log(data))
27 | .catch((error) => console.log("An error occurred while updating the table:" + ' ' + error.message ));
28 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/table_change_to_provisioned.js:
--------------------------------------------------------------------------------
1 | // A simple script to switch a table to provisioned capacity mode.
2 |
3 | const { DynamoDBClient, UpdateTableCommand } = require('@aws-sdk/client-dynamodb');
4 |
5 | const REGION = "us-west-2"; // Replace with your target region
6 | const TableName = "Music"; // Replace with your table name.
7 |
8 | const dbclient = new DynamoDBClient({ region: REGION });
9 |
10 | async function updateTable() {
11 | const params = {
12 | BillingMode: "PROVISIONED",
13 | ProvisionedThroughput: {
14 | ReadCapacityUnits: 5,
15 | WriteCapacityUnits: 4,
16 | },
17 | TableName: TableName,
18 | };
19 | return await dbclient.send( new UpdateTableCommand(params));
20 | // Add code to wait for table update to complete before returning.
21 | }
22 |
23 | updateTable()
24 | .then((data) => console.log(data))
25 | .catch((error) => console.log("An error occurred while updating the table:" + ' ' + error.message ));
26 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/control_plane/WorkingWithTables/update-global-table-and-global-table-settings.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | const dynamodb = new AWS.DynamoDB({ region: "us-west-2" });
4 |
5 | const tableName = "Music";
6 |
7 | // Before using this method, you must create the table in the region.
8 | async function updateGlobalTable() {
9 | const params = {
10 | GlobalTableName: tableName,
11 | ReplicaUpdates: [
12 | {
13 | Create: {
14 | RegionName: "us-east-1",
15 | },
16 | },
17 | ],
18 | };
19 |
20 | const response = await dynamodb.updateGlobalTable(params).promise();
21 | return response;
22 | }
23 |
24 | async function updateGlobalTableSettings() {
25 | const params = {
26 | GlobalTableName: tableName,
27 | GlobalTableProvisionedWriteCapacityUnits: "10",
28 | };
29 |
30 | const response = await dynamodb.updateGlobalTableSettings(params).promise();
31 | return response;
32 | }
33 |
34 | async function updateAll() {
35 | await updateGlobalTable();
36 | await updateGlobalTableSettings();
37 | }
38 |
39 | updateAll().catch((error) => console.error(JSON.stringify(error, null, 2)));
40 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithItems/delete-item.js:
--------------------------------------------------------------------------------
1 | /* This is an example of a DeleteCommand with a ConditionExpression using
2 | the higher level DocumentClient for Amazon DynamoDB. The conditional
3 | expression must be true for this DeleteCommand to succeed. */
4 |
5 | const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
6 | const { DynamoDBDocumentClient, DeleteCommand } = require("@aws-sdk/lib-dynamodb");
7 |
8 | async function deleteItem() {
9 | const client = new DynamoDBClient({ region: "us-west-2" });
10 | const ddbDocClient = DynamoDBDocumentClient.from(client);
11 | return await ddbDocClient.send(
12 | new DeleteCommand({
13 | TableName: "RetailDatabase",
14 | Key: {
15 | pk: "jim.bob@somewhere.com", // Partition key
16 | sk: "metadata", // Sort key
17 | },
18 | // Below is an optional conditional expression to validate the value of the address.pcode
19 | // value is the value provided. If the item matching the partition and sort key are found
20 | // but the values below does not match, then the delete will fail and the item not deleted.
21 | ConditionExpression: "address.pcode = :val",
22 | ExpressionAttributeValues: {
23 | ":val" : "98261",
24 | },
25 | })
26 | );
27 | }
28 |
29 | deleteItem()
30 | .then((data) =>
31 | console.log("DeleteCommand succeeded:", JSON.stringify(data, null, 2)))
32 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithItems/get-item-low-level.js:
--------------------------------------------------------------------------------
1 | /*
2 | This example uses the low level DynamoDB client with the getItem call to get one item from DynamoDB.
3 | */
4 |
5 | const { DynamoDB } = require('@aws-sdk/client-dynamodb');
6 |
7 | async function getItem() {
8 | const params = {
9 | TableName: "RetailDatabase",
10 | Key: {
11 | pk: {S: "jim.bob@somewhere.com"},
12 | sk: {S: "metadata"}
13 | },
14 | };
15 |
16 | const client = new DynamoDB({region: "us-west-2"});
17 | return await client.getItem(params);
18 | }
19 |
20 | getItem()
21 | .then((data) =>
22 | console.log("GetItem succeeded:", JSON.stringify(data.Item, null, 2))
23 | )
24 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithItems/get-item.js:
--------------------------------------------------------------------------------
1 | // This is an example of a simple GetCommand with the higher level DocumentClient for Amazon DynamoDB
2 |
3 | const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
4 | const { DynamoDBDocumentClient, GetCommand } = require("@aws-sdk/lib-dynamodb");
5 |
6 | async function getItems() {
7 | const client = new DynamoDBClient({ region: "us-west-2" });
8 | const ddbDocClient = DynamoDBDocumentClient.from(client);
9 | try {
10 | return await ddbDocClient.send(
11 | new GetCommand({
12 | TableName: "RetailDatabase",
13 | Key: {
14 | pk: "jim.bob@somewhere.com", // Partition Key
15 | sk: "metadata" // Sort Key
16 | },
17 | // For this use case, the data does not changed often so why not get the
18 | // reads at half the cost? Your use case might be different and need true.
19 | ConsistentRead: false,
20 | })
21 | );
22 | } catch (err) {
23 | console.error(err);
24 | }
25 | }
26 |
27 | getItems()
28 | .then((data) =>
29 | console.log("GetCommand succeeded:", JSON.stringify(data, null, 2)))
30 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithItems/put-item.js:
--------------------------------------------------------------------------------
1 | // This is an example of a simple PutCommand using the higher level DocumentClient for Amazon DynamoDB
2 |
3 | const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
4 | const { DynamoDBDocumentClient, PutCommand } = require("@aws-sdk/lib-dynamodb");
5 |
6 | async function putItems() {
7 | const client = new DynamoDBClient({ region: "us-west-2" });
8 | const ddbDocClient = DynamoDBDocumentClient.from(client);
9 |
10 | return await ddbDocClient.send(
11 | new PutCommand({
12 | TableName: "RetailDatabase",
13 | Item: {
14 | pk: "jim.bob@somewhere.com", // Partition Key
15 | sk: "metadata", // Sort Key
16 | name: "Jim Bob",
17 | first_name: "Jim",
18 | last_name: "Roberts",
19 | address: {
20 | road: "456 Nowhere Lane",
21 | city: "Langely",
22 | state: "WA",
23 | pcode: "98260",
24 | country: "USA",
25 | },
26 | username: "jrob",
27 | },
28 | })
29 | );
30 | }
31 |
32 | putItems()
33 | .then((data) =>
34 | console.log("PutCommand succeeded with HTTP code:", JSON.stringify(data.$metadata.httpStatusCode, null, 2)))
35 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
36 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithItems/update-item.js:
--------------------------------------------------------------------------------
1 | /* This is an example of an UpdateCommand using the higher level DocumentClient
2 | for Amazon DynamoDB. It updates one attribute on the item, but it could easily
3 | do more if needed. */
4 |
5 | const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
6 | const { DynamoDBDocumentClient, UpdateCommand } = require("@aws-sdk/lib-dynamodb");
7 |
8 | async function updateItem() {
9 | const client = new DynamoDBClient({ region: "us-west-2" });
10 | const ddbDocClient = DynamoDBDocumentClient.from(client);
11 |
12 | return await ddbDocClient.send(
13 | new UpdateCommand({
14 | TableName: "RetailDatabase",
15 | Key: {
16 | pk: "jim.bob@somewhere.com", // Partition key
17 | sk: "metadata", // Sort key
18 | },
19 | ExpressionAttributeNames: {
20 | "#n": "name",
21 | },
22 | UpdateExpression: "set #n = :nm",
23 | ExpressionAttributeValues: {
24 | ":nm": "Big Jim Bob",
25 | },
26 | ReturnValues: "ALL_NEW",
27 | })
28 | );
29 | }
30 |
31 | updateItem()
32 | .then((data) =>
33 | console.log("UpdateCommand succeeded:", JSON.stringify(data, null, 2)))
34 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithPartiQL/execute-statement.js:
--------------------------------------------------------------------------------
1 | const REGION = "us-west-2";
2 | // I am using the DynamoDB low level because the DocClient does not support executeStatement used with PartiQL
3 | const { DynamoDB } = require("@aws-sdk/client-dynamodb");
4 | const { unmarshall } = require("@aws-sdk/util-dynamodb");
5 |
6 | // Create low level client
7 | const dbclient = new DynamoDB({ region: REGION });
8 |
9 | const pk = "TEAM";
10 |
11 | // In PartiQL, we can execute statement with execute-statement which performs one action similar to Scan/Query.
12 | const params = { Statement: `SELECT * FROM "copa-america" WHERE "pk" = ?`,
13 | Parameters: [{"S": pk}]
14 | };
15 |
16 | const executePartiQLStatement = async () => {
17 | return data = await dbclient.executeStatement(params);
18 | }
19 |
20 | executePartiQLStatement()
21 | .then((data) => {
22 | //Iterate through the Items array returned in the data variable and then unmarshall the DynamoDB JSON format to "regular" json format.
23 | data.Items.forEach(function (item) {
24 | console.log(JSON.stringify(unmarshall(item), null, 2));
25 | });
26 | }
27 | )
28 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
29 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithPartiQL/execute-transaction.js:
--------------------------------------------------------------------------------
1 | const REGION = "us-west-2";
2 | const { DynamoDB } = require("@aws-sdk/client-dynamodb");
3 | const { unmarshall } = require("@aws-sdk/util-dynamodb");
4 |
5 | // Create low level client
6 | const dbclient = new DynamoDB({ region: REGION });
7 |
8 | // In PartiQL, we can execute statement with execute-transaction which performs multiple operations similar to batch operations.
9 | const params = [{
10 | Statement: `SELECT * FROM "copa-america" WHERE "pk" = 'MATCH'`,
11 | }]
12 |
13 | const executePartiQLStatement = async () => {
14 | return data = await dbclient.executeTransaction(params);
15 | }
16 |
17 | executePartiQLStatement()
18 | .then((data) => {
19 | //Iterate through the Items array returned in the data variable and then unmarshall the DynamoDB JSON format to "regular" json format.
20 | data.Items.forEach(function (item) {
21 | console.log(JSON.stringify(unmarshall(item), null, 2));
22 | });
23 | }
24 | )
25 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
26 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithQueries/query-key-condition-expression-begins-with.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2 | import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
3 |
4 | const client = new DynamoDBClient({ region: "us-west-2" });
5 | const docClient = DynamoDBDocumentClient.from(client);
6 |
7 | const query = async () => {
8 | const params = {
9 | TableName: "Reply",
10 | KeyConditionExpression: "#id = :id and begins_with(#dt, :dt)",
11 | ExpressionAttributeNames: {
12 | "#id": "Id",
13 | "#dt": "ReplyDateTime",
14 | },
15 | ExpressionAttributeValues: {
16 | ":id": "Amazon DynamoDB#DynamoDB Thread 1",
17 | ":dt": "2015-09",
18 | },
19 | };
20 |
21 | try {
22 | const response = await docClient.send(new QueryCommand(params));
23 |
24 | // Check if there are more results to retrieve
25 | if (response.LastEvaluatedKey) {
26 | console.log(
27 | `Not all items have been retrieved by this query. At least one another request is required to get all available items. The last evaluated key corresponds to ${JSON.stringify(response.LastEvaluatedKey)}.`
28 | );
29 | }
30 | return response;
31 | } catch (error) {
32 | console.error("Error querying DynamoDB:", error);
33 | throw error;
34 | }
35 | };
36 |
37 | query()
38 | .then((response) => console.log(`Query response: ${JSON.stringify(response, null, 2)}`))
39 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
40 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithQueries/query-key-condition-expression-equals.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2 | import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
3 |
4 | const client = new DynamoDBClient({ region: "us-west-2" });
5 | const docClient = DynamoDBDocumentClient.from(client);
6 |
7 | const query = async () => {
8 | const params = {
9 | TableName: "Thread",
10 | KeyConditionExpression: "#fn = :name AND #sub = :sub",
11 | ExpressionAttributeNames: {
12 | "#fn": "ForumName",
13 | "#sub": "Subject",
14 | },
15 | ExpressionAttributeValues: {
16 | ":name": "Amazon DynamoDB",
17 | ":sub": "DynamoDB Thread 1",
18 | },
19 | };
20 |
21 | try {
22 | // Send the query command
23 | const response = await docClient.send(new QueryCommand(params));
24 |
25 | // We don't need to check for more items since when we specify an explicit partition key and
26 | // sort key on the primary table, we are guaranteed to get zero or one item back.
27 |
28 | return response;
29 | } catch (error) {
30 | console.error("Error querying DynamoDB:", error);
31 | throw error;
32 | }
33 | };
34 |
35 | query()
36 | .then((response) => console.log(`Query response: ${JSON.stringify(response, null, 2)}`))
37 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
38 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithQueries/query-projection-expression.js:
--------------------------------------------------------------------------------
1 | import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
2 | import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
3 |
4 | const client = new DynamoDBClient({ region: "us-west-2" });
5 | const docClient = DynamoDBDocumentClient.from(client);
6 |
7 | const query = async () => {
8 | const params = {
9 | TableName: "Music",
10 | ExpressionAttributeValues: {
11 | ":pk": "Michael Jackson",
12 | },
13 | KeyConditionExpression: "Artist = :pk",
14 | ProjectionExpression: "SongTitle, Album",
15 | };
16 |
17 | try {
18 | // Send the query command
19 | const response = await docClient.send(new QueryCommand(params));
20 |
21 | // Check if there are more results to retrieve
22 | if (response.LastEvaluatedKey) {
23 | console.log(
24 | `Not all items have been retrieved by this query. At least one another request is required to get all available items. The last evaluated key corresponds to ${JSON.stringify(response.LastEvaluatedKey)}.`
25 | );
26 | }
27 |
28 | return response;
29 | } catch (error) {
30 | console.error("Error querying DynamoDB:", error);
31 | throw error;
32 | }
33 | };
34 |
35 | query()
36 | .then((response) => console.log(`Query response: ${JSON.stringify(response, null, 2)}`))
37 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
38 |
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithScans/scan-fetch-all-pagination.js:
--------------------------------------------------------------------------------
1 | /*
2 | This code uses a page size of 100 and will bring back all items in a table.
3 | It uses the "low-level" JS client, not the DocumentClient, thus the data is
4 | returned in DynamoDB's native JSON format. If you want plain JSON, you can
5 | either convert this to use the DocumentClient or use unmarshall util
6 | */
7 |
8 | const { DynamoDBClient, paginateScan } = require('@aws-sdk/client-dynamodb');
9 |
10 | const dynamodb = new DynamoDBClient({});
11 |
12 | async function fetchAll() {
13 | const config = {
14 | client: dynamodb,
15 | pageSize: 100
16 | };
17 | const input = {
18 | TableName: 'RetailDatabase'
19 | };
20 | const paginator = paginateScan(config, input);
21 | for await (const page of paginator) {
22 | page.Items.forEach(console.log);
23 | }
24 | }
25 |
26 | fetchAll()
27 | .then(() => console.log('done'))
28 | .catch(() => process.exit(1));
--------------------------------------------------------------------------------
/examples/SDK/node.js/sdk_v3/data_plane/WorkingWithScans/scan-parallel-segments.js:
--------------------------------------------------------------------------------
1 | const AWS = require("aws-sdk");
2 |
3 | AWS.config.update({ region: "us-west-2" });
4 |
5 | const documentClient = new AWS.DynamoDB.DocumentClient();
6 | const segments = 5;
7 |
8 | // Define a total number segments to scan across, and execute multiple table scans asynchronously.
9 | async function parallelScan(segments = 1) {
10 | let results = [];
11 | for (let i = 0; i < segments; i++) {
12 | let scan = documentClient
13 | .scan({
14 | TableName: "Products",
15 | FilterExpression: "#status = :status",
16 | ExpressionAttributeNames: {
17 | "#status": "ProductStatus",
18 | },
19 | ExpressionAttributeValues: {
20 | ":status": "IN_STOCK",
21 | },
22 | TotalSegments: segments, // The total number of segments to scan across, in this case 5.
23 | Segment: i, // The segment index for this particular query, zero indexed, in this case 0-4.
24 | })
25 | .promise();
26 | // Push unsettled scan Promise into results array.
27 | results.push(scan);
28 | }
29 | // Use Promise.all to return all scan results as a single Promise.
30 | return Promise.all(results);
31 | }
32 |
33 | parallelScan(segments)
34 | .then((scans) => console.log("ParallelScan succeeded:", scans.length))
35 | .catch((error) => console.error(JSON.stringify(error, null, 2)));
36 |
--------------------------------------------------------------------------------
/examples/SDK/python/WorkingWithTestData/test_data_generator.py:
--------------------------------------------------------------------------------
1 | from logging import error
2 | import os
3 | import boto3
4 | import hashlib
5 | from botocore.exceptions import ClientError
6 |
7 |
8 | dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
9 |
10 | # make sure Music or your custom table exists and change attributes and primary key accordingly
11 | table = dynamodb.Table('Music')
12 | # table schema Music table, string artist (PKHash), string title (PK-Sort), string attribute (string attribute)
13 |
14 | #each item will be approx. 20kb hence set counter limit accordingly
15 | counter = 0
16 | COUNTER_LIMIT = 12
17 |
18 | while True:
19 | print("\n loop " + str(counter) + "\n")
20 | pk_str = "batman" + str(counter)
21 | pk_hash = hashlib.md5(pk_str.encode()).hexdigest()
22 | pk_sort_str = "happy" + str(counter)
23 | pk_sort_hash = hashlib.md5(pk_sort_str.encode()).hexdigest()
24 | attribute = os.urandom(10240).hex()
25 | try:
26 | response = table.put_item(
27 | Item={
28 | 'artist': pk_hash,
29 | 'title': pk_sort_hash,
30 | 'album': attribute
31 | })
32 | except ClientError as error:
33 | print('Error happened')
34 |
35 | counter += 1
36 | if counter > COUNTER_LIMIT:
37 | print("We have added {} item each nearly 20kb".format(COUNTER_LIMIT))
38 | break
39 |
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithIndexes/add_gsi.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.Table("RetailDatabase") # Substitute your table name for RetailDatabase
7 |
8 | table.update(
9 | AttributeDefinitions=[
10 | {
11 | 'AttributeName': 'status',
12 | 'AttributeType': 'S'
13 | },
14 | {
15 | 'AttributeName': 'GSI2-SK',
16 | 'AttributeType': 'S'
17 | },
18 | ],
19 | GlobalSecondaryIndexUpdates=[
20 | {
21 | 'Create': {
22 | 'IndexName': 'VendorOrdersByStatusDate-ProductInventor',
23 | 'KeySchema': [
24 | {
25 | 'AttributeName': 'status',
26 | 'KeyType': 'HASH' # could be 'HASH'|'RANGE'
27 | },
28 | {
29 | 'AttributeName': 'GSI2-SK',
30 | 'KeyType': 'RANGE' # could be 'HASH'|'RANGE'
31 | },
32 | ],
33 | 'Projection': {
34 | 'ProjectionType': 'KEYS_ONLY', # could be 'ALL'|'KEYS_ONLY'|'INCLUDE'
35 |
36 | },
37 | },
38 | },
39 | ],
40 | )
41 |
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/add_global_table_region.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2') # substitute your preferred region
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name
7 |
8 | #Add a region to an existing table. If streams is not already enabled, the enables it.
9 | table.update(
10 | ReplicaUpdates=[
11 | {
12 | 'Create': {
13 | 'RegionName': 'us-east-2',
14 | },
15 | }
16 | ]
17 | )
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/add_provisioned_capacity.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name
7 |
8 | table.update(
9 | ProvisionedThroughput={
10 | 'ReadCapacityUnits': 10,
11 | 'WriteCapacityUnits': 5
12 | }
13 | )
14 |
15 | table.meta.client.get_waiter('table_exists').wait(TableName='Music')
16 | print('Table updated.')
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/create_table_on-demand.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import print_function # Python 2/3 compatibility
3 | import boto3
4 |
5 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
6 |
7 | table = dynamodb.create_table(
8 | TableName="Music", # Substitute your table name for RetailDatabase
9 | BillingMode="PAY_PER_REQUEST",
10 | KeySchema=[
11 | {
12 | 'AttributeName': 'Artist',
13 | 'KeyType': 'HASH' #Partition key
14 | },
15 | {
16 | 'AttributeName': 'SongTitle',
17 | 'KeyType': 'RANGE' #Sort key
18 | }
19 | ],
20 | AttributeDefinitions=[
21 | {
22 | 'AttributeName': 'Artist',
23 | 'AttributeType': 'S'
24 | },
25 | {
26 | 'AttributeName': 'SongTitle',
27 | 'AttributeType': 'S'
28 | },
29 | ],
30 | )
31 |
32 | table.meta.client.get_waiter('table_exists').wait(TableName='Music')
33 | print('Table has been created, please continue to insert data.')
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/create_table_provisioned.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.create_table(
7 | TableName="Music", # Substitute your table name for RetailDatabase
8 | BillingMode="PROVISIONED",
9 | KeySchema=[
10 | {
11 | 'AttributeName': 'Artist',
12 | 'KeyType': 'HASH' #Partition key
13 | },
14 | {
15 | 'AttributeName': 'SongTitle',
16 | 'KeyType': 'RANGE' #Sort key
17 | }
18 | ],
19 | AttributeDefinitions=[
20 | {
21 | 'AttributeName': 'Artist',
22 | 'AttributeType': 'S'
23 | },
24 | {
25 | 'AttributeName': 'SongTitle',
26 | 'AttributeType': 'S'
27 | },
28 | ],
29 | ProvisionedThroughput={
30 | 'ReadCapacityUnits': 5,
31 | 'WriteCapacityUnits': 10
32 | },
33 | )
34 |
35 | table.meta.client.get_waiter('table_exists').wait(TableName='Music')
36 | print('Table created, please continue to insert data.')
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/delete_global_table_region.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2') # substitute your preferred region
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name for RetailDatabase
7 |
8 | # Delete a region to an existing table.
9 | table.update(
10 | ReplicaUpdates=[
11 | {
12 | 'Delete': {
13 | 'RegionName': 'us-east-2',
14 | },
15 | }
16 | ]
17 | )
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/delete_table.py:
--------------------------------------------------------------------------------
1 | // Be advised that when you delete a table, it does not delete auto-scaling info (e.g. scalable
2 | // targets, scaling policies) or CloudWatch alarms. This must be done in seperate calls.
3 |
4 | from __future__ import print_function # Python 2/3 compatibility
5 | import boto3, pprint
6 |
7 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
8 |
9 | table = dynamodb.Table("Music") # Substitute your table name for RetailDatabase
10 |
11 | response = table.delete()
12 |
13 | pprint.pprint(response)
14 |
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/describe_limits.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | # create the resource we need to connect.
5 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
6 |
7 | # get the table limits from the table object
8 | response = dynamodb.meta.client.describe_limits()
9 |
10 | pprint.pprint(response)
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/describe_table.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | #table = dynamodb.Table("Music") # Substitute your table name for RetailDatabase
7 |
8 | response = dynamodb.meta.client.describe_table(
9 | TableName='Music'
10 | )
11 |
12 | pprint.pprint(response)
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/disable_auto-scaling.py:
--------------------------------------------------------------------------------
1 | import boto3
2 | aas_client = boto3.client('application-autoscaling')
3 | #iam_client = boto3.client('iam')
4 |
5 | table_name = "Music" # Add the name of the DynamoDB table you want to add auto-scaling to between the double quotes.
6 |
7 | # detach the Write scaling policy to the table.
8 | response = aas_client.delete_scaling_policy(
9 | PolicyName='{}ScalingPolicy'.format(table_name),
10 | ServiceNamespace='dynamodb',
11 | ResourceId='table/{}'.format(table_name),
12 | ScalableDimension='dynamodb:table:WriteCapacityUnits'
13 | )
14 |
15 | # detach the Read scaling policy to the table.
16 | response = aas_client.delete_scaling_policy(
17 | PolicyName='{}ScalingPolicy'.format(table_name),
18 | ServiceNamespace='dynamodb',
19 | ResourceId='table/{}'.format(table_name),
20 | ScalableDimension='dynamodb:table:ReadCapacityUnits'
21 | )
22 |
23 | # Deregister the RCU targets for the table
24 | response = aas_client.deregister_scalable_target(
25 | ServiceNamespace='dynamodb',
26 | ResourceId='table/{}'.format(table_name),
27 | ScalableDimension='dynamodb:table:ReadCapacityUnits',
28 | )
29 |
30 | # Deregister the WCU targets for the table
31 | response = aas_client.deregister_scalable_target(
32 | ServiceNamespace='dynamodb',
33 | ResourceId='table/{}'.format(table_name),
34 | ScalableDimension='dynamodb:table:WriteCapacityUnits',
35 | )
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/enable_continuous_backups.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import print_function # Python 2/3 compatibility
3 | import boto3, pprint
4 |
5 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
6 |
7 | table = dynamodb.Table("Music") # Substitute your table name
8 |
9 | response = table.meta.client.update_continuous_backups(
10 | TableName='RetailDatabase',
11 | PointInTimeRecoverySpecification={
12 | 'PointInTimeRecoveryEnabled': True # options are True|False
13 | }
14 | )
15 |
16 | # Print the JSON response
17 | pprint.pprint(response)
18 |
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/enable_streams.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name
7 |
8 | table.update(
9 | StreamSpecification={
10 | 'StreamEnabled': True,
11 | 'StreamViewType': 'NEW_AND_OLD_IMAGES' # Could be any of the following values 'NEW_IMAGE'|'OLD_IMAGE'|'NEW_AND_OLD_IMAGES'|'KEYS_ONLY'
12 | },
13 | )
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/list_tables.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | # create the resource we need to connect.
5 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
6 |
7 | # get the table limits from the table object
8 | response = dynamodb.meta.client.list_tables()
9 |
10 | pprint.pprint(response)
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/update_table_on-demand.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name
7 |
8 | table.update(
9 | BillingMode="PAY_PER_REQUEST"
10 | )
11 |
--------------------------------------------------------------------------------
/examples/SDK/python/control_plane/WorkingWithTables/update_table_provisioned.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, pprint
3 |
4 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
5 |
6 | table = dynamodb.Table("Music") # Substitute your table name
7 |
8 | table.update(
9 | ProvisionedThroughput={
10 | 'ReadCapacityUnits': 10,
11 | 'WriteCapacityUnits': 10
12 | }
13 | )
14 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/delete_item.py:
--------------------------------------------------------------------------------
1 | # Simple delete item call, but with an optional condition expression to only delete if the postal code is a specific value
2 | from __future__ import print_function # Python 2/3 compatibility
3 | import boto3, json
4 | from botocore.exceptions import ClientError
5 |
6 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
7 |
8 | table = dynamodb.Table('RetailDatabase')
9 |
10 | try:
11 | response = table.delete_item(
12 | Key={
13 | 'pk': "jim.bob",
14 | "sk": "metadata"
15 | },
16 | ConditionExpression="shipaddr.pcode = :val",
17 | ExpressionAttributeValues= {
18 | ":val": "98260"
19 | }
20 | )
21 | except ClientError as e:
22 | if e.response['Error']['Code'] == "ConditionalCheckFailedException":
23 | print(e.response['Error']['Message'])
24 | else:
25 | raise
26 | else:
27 | print("DeleteItem succeeded:")
28 | print(json.dumps(response, indent=4, sort_keys=True))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/delete_item_conditional.py:
--------------------------------------------------------------------------------
1 | # Normally if you just delete an item and that item does not exists, a delete successful message is still returned.
2 | # What if you want an error to be thrown?
3 | # Theisexample will delete an item using a conditional delete, but return an error if the item does not exist.
4 | # It just looks for the existence of the item with this primary key, but that those attributes exist. If the item does
5 | # exist, it is deleted. If it does not exist, you get "The conditional request failed".
6 |
7 |
8 | from __future__ import print_function # Python 2/3 compatibility
9 | import boto3, json
10 | from botocore.exceptions import ClientError
11 |
12 |
13 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
14 |
15 | table = dynamodb.Table('RetailDatabase')
16 |
17 |
18 | try:
19 | response = table.delete_item(
20 | Key={
21 | 'pk': "jim.bob",
22 | "sk": "metadata"
23 | },
24 | ConditionExpression="attribute_exists (pk) AND attribute_exists (sk)",
25 | )
26 | except ClientError as e:
27 | if e.response['Error']['Code'] == "ConditionalCheckFailedException":
28 | print(e.response['Error']['Message'])
29 | else:
30 | raise
31 | else:
32 | print("DeleteItem succeeded:")
33 | print(json.dumps(response, indent=4, sort_keys=True))
34 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/get_item.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json, decimal
3 |
4 | from boto3.dynamodb.conditions import Key, Attr
5 | from botocore.exceptions import ClientError
6 |
7 | # Helper class to convert a DynamoDB item to JSON.
8 | class DecimalEncoder(json.JSONEncoder):
9 | def default(self, o):
10 | if isinstance(o, decimal.Decimal):
11 | if o % 1 > 0:
12 | return float(o)
13 | else:
14 | return int(o)
15 | return super(DecimalEncoder, self).default(o)
16 |
17 | dynamodb = boto3.resource("dynamodb", region_name='us-west-2')
18 |
19 | table = dynamodb.Table('RetailDatabase')
20 |
21 | try:
22 | response = table.get_item(
23 | Key={
24 | 'pk': "jim.bob",
25 | 'sk': "metadata"
26 | }
27 | )
28 | except ClientError as e:
29 | print(e.response['Error']['Message'])
30 | else:
31 | print("GetItem succeeded:")
32 | print(json.dumps(response['Item'], indent=4, cls=DecimalEncoder))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/put_item.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json, decimal
3 |
4 | from botocore.exceptions import ClientError
5 |
6 | # Helper class to convert a DynamoDB item to JSON.
7 | class DecimalEncoder(json.JSONEncoder):
8 | def default(self, o):
9 | if isinstance(o, decimal.Decimal):
10 | if abs(o) % 1 > 0:
11 | return float(o)
12 | else:
13 | return int(o)
14 | return super(DecimalEncoder, self).default(o)
15 |
16 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
17 |
18 | table = dynamodb.Table('RetailDatabase')
19 |
20 | #Insert new user data into the system
21 | try:
22 | response = table.put_item(
23 | Item={
24 | 'pk': "jim.bob@somewhere.com",
25 | 'sk': "metadata",
26 | 'name': "Jim Bob",
27 | 'first_name': "Jim",
28 | 'last_name': "Bob",
29 | 'address': {
30 | 'road': "456 Nowhere Lane",
31 | 'city': "Langely",
32 | 'state': "WA",
33 | 'pcode': "98260",
34 | 'country': "USA"
35 | },
36 | 'username': "jbob"
37 | }
38 | )
39 | except ClientError as e:
40 | print(e.response['Error']['Message'])
41 | else:
42 | print("PutItem succeeded:")
43 | print(json.dumps(response, indent=4, cls=DecimalEncoder))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/transact_get.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json, decimal
3 | from boto3.dynamodb.conditions import Key, Attr
4 | from botocore.exceptions import ClientError
5 |
6 | client = boto3.client('dynamodb', region_name='us-west-2')
7 |
8 | try:
9 | response = client.transact_get_items(
10 | TransactItems=[
11 | {
12 | 'Get': {
13 | 'TableName': "RetailDatabase",
14 | 'Key': {
15 | 'PK': {
16 | 'S': '123'
17 | },
18 | 'SK': {
19 | 'S': "abc"
20 | },
21 | },
22 | },
23 | },
24 | {
25 | 'Get': {
26 | 'TableName': "RetailDatabase",
27 | 'Key': {
28 | 'PK': {
29 | 'S': "789"
30 | },
31 | 'SK': {
32 | 'S': "xyz"
33 | },
34 | },
35 | },
36 | },
37 | ]
38 | )
39 |
40 | print(json.dumps(response))
41 |
42 | except ClientError as e:
43 | print(e.response['Error']['Message'])
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithItems/updating_item.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json
3 | from botocore.exceptions import ClientError
4 |
5 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
6 |
7 | table = dynamodb.Table('RetailDatabase')
8 |
9 | # Update the name of a user account. Note that in this example, we have to alias "name" using ExpressionAttributeNames as name is a reserved word in DynamoDB.
10 | try:
11 | response = table.update_item(
12 | Key={
13 | 'pk': "jim.bob",
14 | "sk": "metadata"
15 | },
16 | ExpressionAttributeNames={"#n": "name"},
17 | UpdateExpression="set #n = :nm",
18 | ExpressionAttributeValues={
19 | ':nm': "Big Jim Bob"
20 | },
21 | ReturnValues="UPDATED_NEW"
22 | )
23 | except ClientError as e:
24 | print(e.response['Error']['Message'])
25 | else:
26 | print("GetItem succeeded:")
27 | print(json.dumps(response, indent=4, sort_keys=True))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithPartiQL/batch-execute-statement.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json
3 |
4 | from botocore.exceptions import ClientError
5 |
6 | # Create low level client
7 | session = boto3.session.Session()
8 | client = session.client('dynamodb')
9 |
10 | data = [
11 | {
12 | "pk": "1",
13 | "sk": "metadata"
14 | },
15 | {
16 | "pk": "2",
17 | "sk": "metadata"
18 | }
19 | ]
20 | statements = []
21 | for item in data:
22 | statement = {'Statement': "INSERT INTO ExampleTable VALUE {'pk':'%s','sk':'%s'}" % (item["pk"], item["sk"])}
23 | statements.append(statement)
24 | try:
25 | response = client.batch_execute_statement(
26 | Statements=statements
27 | )
28 | print(response)
29 | except ClientError as e:
30 | print(e.response['Error']['Message'])
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithPartiQL/execute-statement.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json
3 |
4 | from botocore.exceptions import ClientError
5 |
6 | # Create low level client
7 | session = boto3.session.Session()
8 | client = session.client('dynamodb')
9 |
10 | pk = "1"
11 |
12 | try:
13 | response = client.execute_statement(
14 | Statement= 'SELECT * FROM ExampleTable WHERE "pk" = ?',
15 | Parameters= [{"S": pk}]
16 | )
17 | except ClientError as e:
18 | print(e.response['Error']['Message'])
19 | else:
20 | print("The PartiQL query returned the following items:")
21 | for item in response['Items']:
22 | print(json.dumps(item, indent=4, sort_keys=True))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithPartiQL/execute-transaction.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json
3 |
4 | from botocore.exceptions import ClientError
5 |
6 | # Create low level client
7 | session = boto3.session.Session()
8 | client = session.client('dynamodb')
9 |
10 | data = [
11 | {
12 | "pk": "1",
13 | "sk": "metadata"
14 | },
15 | {
16 | "pk": "2",
17 | "sk": "metadata"
18 | }
19 | ]
20 | statements = []
21 | for item in data:
22 | statement = {'Statement': "INSERT INTO ExampleTable VALUE {'pk':'%s','sk':'%s'}" % (item["pk"], item["sk"])}
23 | statements.append(statement)
24 | try:
25 | response = client.execute_transaction(
26 | TransactStatements=statements
27 | )
28 | print(response)
29 | except ClientError as e:
30 | print("ClientError")
31 | print(e.response['Error']['Message'])
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithPartiQL/paginated-select-statement.py:
--------------------------------------------------------------------------------
1 | import boto3
2 |
3 | from botocore.exceptions import ClientError
4 |
5 | # execute statment works with low level client.
6 | dynamodb = boto3.client('dynamodb', region_name='us-east-1')
7 | params = {
8 | 'statement': 'SELECT * FROM "cerberus-test-3"',
9 | 'next_token': None
10 | }
11 |
12 | # Shows we cannot use inbuilt pagination for execute statement.
13 | print(dynamodb.can_paginate('execute_statement'))
14 |
15 | while True:
16 | try:
17 | if params['next_token'] is None:
18 | response = dynamodb.execute_statement(
19 | Statement=params['statement'])
20 |
21 | elif params['next_token']:
22 | response = dynamodb.execute_statement(
23 | Statement=params['statement'], NextToken=params['next_token'])
24 |
25 | # for paginated results response includes nexttoken which can be used for pagination
26 | if 'NextToken' in response:
27 | params['next_token'] = response['NextToken']
28 | print("Next token is updated")
29 | else:
30 | print("paginated statement executed succesfully")
31 | break
32 | except ClientError as error:
33 | print(error)
34 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithPartiQL/simple-select-statement.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3, json
3 |
4 | from botocore.exceptions import ClientError
5 |
6 | # Create low level client
7 | session = boto3.session.Session()
8 | client = session.client('dynamodb')
9 |
10 | pk = "1"
11 | sk = "metadata"
12 |
13 | try:
14 | response = client.execute_statement(
15 | Statement= 'SELECT * FROM ExampleTable WHERE "pk" = ? AND "sk" = ?',
16 | Parameters= [{"S": pk}, {"S": sk}]
17 | )
18 | except ClientError as e:
19 | print(e.response['Error']['Message'])
20 | else:
21 | print("The PartiQL query returned the following items:")
22 | for item in response['Items']:
23 | print(json.dumps(item, indent=4, sort_keys=True))
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/pagination.py:
--------------------------------------------------------------------------------
1 | # snippet-sourcedescription:[ pagination through a list of items from a query ]
2 | # snippet-service:[dynamodb]
3 | # snippet-keyword:[Python]
4 | # snippet-keyword:[Amazon DynamoDB]
5 | # snippet-keyword:[Code Sample]
6 | # snippet-keyword:[ Pagination]
7 | # snippet-sourcetype:[full-example]
8 | # snippet-sourcedate:[ ]
9 | # snippet-sourceauthor:[AWS]
10 | # snippet-start:[dynamodb.python.codeexample.pagination]
11 |
12 | #
13 | # Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
14 | #
15 | # This file is licensed under the Apache License, Version 2.0 (the "License").
16 | # You may not use this file except in compliance with the License. A copy of
17 | # the License is located at
18 | #
19 | # http://aws.amazon.com/apache2.0/
20 | #
21 | # This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
22 | # CONDITIONS OF ANY KIND, either express or implied. See the License for the
23 | # specific language governing permissions and limitations under the License.
24 | #
25 | from __future__ import print_function # Python 2/3 compatibility
26 | import boto3, json, decimal
27 |
28 | from boto3.dynamodb.conditions import Key, Attr
29 | from botocore.exceptions import ClientError
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/query-consistent-read.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | import json
4 | import decimal
5 | from boto3.dynamodb.conditions import Key, Attr
6 | from botocore.exceptions import ClientError
7 |
8 |
9 | # Helper class to convert a DynamoDB item to JSON.
10 | class DecimalEncoder(json.JSONEncoder):
11 | def default(self, o):
12 | if isinstance(o, decimal.Decimal):
13 | return str(o)
14 | return super(DecimalEncoder, self).default(o)
15 |
16 |
17 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
18 |
19 | table = dynamodb.Table('Music')
20 |
21 | try:
22 | response = table.query(
23 | ExpressionAttributeNames={
24 | '#pk': 'Artist',
25 | },
26 | ExpressionAttributeValues={
27 | ':pk': 'Michael Jackson',
28 | },
29 | KeyConditionExpression='#pk = :pk',
30 | ConsistentRead=True
31 | )
32 | except ClientError as e:
33 | print(e.response['Error']['Message'])
34 | else:
35 | if 'LastEvaluatedKey' in response:
36 | print('Not all items have been retrieved by this query. At least one another request is required to get all available items. The last evaluated key corresponds to',
37 | json.dumps(response['LastEvaluatedKey'], indent=4, cls=DecimalEncoder))
38 |
39 | print('Query response:', json.dumps(response, indent=4, cls=DecimalEncoder))
40 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/query_begins_with.py:
--------------------------------------------------------------------------------
1 | import boto3, json
2 | from boto3.dynamodb.conditions import Key
3 |
4 | # boto3 is the AWS SDK library for Python.
5 | # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
6 | # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
7 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
8 | table = dynamodb.Table('RetailDatabase')
9 |
10 | # When making a Query API call, we use the KeyConditionExpression parameter to specify the partition key on which we want to query.
11 | # We're using the Key object from the Boto3 library to specify that we want the attribute name ("pk")
12 | # to equal "helga.ramirez@somewhere.com" by using the ".eq()" method. Further we get all of those items that have a sort key using the
13 | # "begins_with()" method to look for "meta::".
14 | resp = table.query(KeyConditionExpression=Key('pk').eq('helga.ramirez@somewhere.com') & Key('sk').begins_with('meta::'))
15 |
16 | print("The query returned the following items:")
17 | for item in resp['Items']:
18 | print(json.dumps(item, indent=4, sort_keys=True))
19 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/query_equals.py:
--------------------------------------------------------------------------------
1 | import boto3, json
2 | from boto3.dynamodb.conditions import Key
3 |
4 | # boto3 is the AWS SDK library for Python.
5 | # The "resources" interface allows for a higher-level abstraction than the low-level client interface.
6 | # For more details, go to http://boto3.readthedocs.io/en/latest/guide/resources.html
7 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
8 | table = dynamodb.Table('RetailDatabase')
9 |
10 | # When making a Query API call, we use the KeyConditionExpression parameter to specify the partition key on which we want to query.
11 | # We're using the Key object from the Boto3 library to specify that we want the attribute name ("pk")
12 | # to equal "helga.ramirez@somewhere.com" by using the ".eq()" method.
13 | resp = table.query(KeyConditionExpression=Key('pk').eq('helga.ramirez@somewhere.com'))
14 |
15 | print("The query returned the following items:")
16 | for item in resp['Items']:
17 | print(json.dumps(item, indent=4, sort_keys=True))
18 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/query_filter_expression.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | import json
4 | import decimal
5 | from boto3.dynamodb.conditions import Key, Attr
6 | from botocore.exceptions import ClientError
7 |
8 |
9 | # Helper class to convert a DynamoDB item to JSON.
10 | class DecimalEncoder(json.JSONEncoder):
11 | def default(self, o):
12 | if isinstance(o, decimal.Decimal):
13 | return str(o)
14 | return super(DecimalEncoder, self).default(o)
15 |
16 |
17 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
18 |
19 | table = dynamodb.Table('Music')
20 |
21 | try:
22 | response = table.query(
23 | KeyConditionExpression=Key('Artist').eq('Michael Jackson'),
24 | FilterExpression=Attr('Year').eq(2012)
25 | )
26 | except ClientError as e:
27 | print(e.response['Error']['Message'])
28 | else:
29 | print('Query response:', json.dumps(response, indent=4, cls=DecimalEncoder))
30 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithQueries/query_projection_expression.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | import json
4 | import decimal
5 | from boto3.dynamodb.conditions import Key
6 | from botocore.exceptions import ClientError
7 |
8 |
9 | # Helper class to convert a DynamoDB item to JSON.
10 | class DecimalEncoder(json.JSONEncoder):
11 | def default(self, o):
12 | if isinstance(o, decimal.Decimal):
13 | return str(o)
14 | return super(DecimalEncoder, self).default(o)
15 |
16 |
17 | dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
18 |
19 | table = dynamodb.Table('Music')
20 |
21 | try:
22 | response = table.query(
23 | KeyConditionExpression=Key('Artist').eq('Michael Jackson'),
24 | ProjectionExpression='SongTitle, Album'
25 | )
26 | except ClientError as e:
27 | print(e.response['Error']['Message'])
28 | else:
29 | print('Query response:', json.dumps(response, indent=4, cls=DecimalEncoder))
30 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithScans/scan_filter_expression.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | from botocore.exceptions import ClientError
4 |
5 | # Create Client
6 | session = boto3.session.Session()
7 | dynamoDbClient = session.client('dynamodb')
8 |
9 | # Table Name
10 | table_name = 'AmazonBins'
11 |
12 | try:
13 | # Scan up to 1mb of data
14 | response = dynamoDbClient.scan(
15 | TableName=table_name,
16 | FilterExpression='begins_with(#a, :r)',
17 | ExpressionAttributeValues={
18 | ':r': {
19 | 'S': '159240'
20 | }
21 | },
22 | ExpressionAttributeNames={
23 | '#a': 'asin',
24 | }
25 | )
26 |
27 | # Print number of items returned
28 | print("Items Returned: {}".format(len(response['Items'])))
29 |
30 | # Show first item in list
31 | print(response['Items'][0])
32 |
33 | except ClientError as error:
34 | print("Something went wrong: ")
35 | print(error.response['ResponseMetadata'])
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithScans/scan_paginate.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | from botocore.exceptions import ClientError
4 |
5 | # Create Client
6 | session = boto3.session.Session()
7 | dynamoDbClient = session.client('dynamodb')
8 |
9 | table_name = 'AmazonBins'
10 |
11 | # Track number of Items read
12 | item_count = 0
13 |
14 | try:
15 | # Get first 1MB of data
16 | response = dynamoDbClient.scan(
17 | TableName=table_name
18 | )
19 |
20 | except ClientError as error:
21 | print("Something went wrong: ")
22 | print(error.response['ResponseMetadata'])
23 |
24 | # Track number of Items read
25 | item_count += len(response['Items'])
26 |
27 | # Paginate returning up to 1MB of data each iteration
28 | while 'LastEvaluatedKey' in response:
29 | try:
30 | response = dynamoDbClient.scan(
31 | TableName=table_name,
32 | ExclusiveStartKey=response['LastEvaluatedKey']
33 | )
34 | # Track number of Items read
35 | item_count += len(response['Items'])
36 |
37 | except ClientError as error:
38 | print("Something went wrong: ")
39 | print(error.response['ResponseMetadata'])
40 |
41 |
42 | print("Total number of items found: {}".format(item_count))
43 |
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithScans/scan_projection_expression.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | from botocore.exceptions import ClientError
4 |
5 | # Create Client
6 | session = boto3.session.Session()
7 | dynamoDbClient = session.client('dynamodb')
8 |
9 | # Table Name
10 | table_name = 'AmazonBins'
11 |
12 | try:
13 | # Scan up to 1mb of data
14 | response = dynamoDbClient.scan(
15 | TableName=table_name,
16 | ProjectionExpression="asin"
17 | )
18 |
19 | # Print number of items returned
20 | print("Items Returned: {}".format(len(response['Items'])))
21 |
22 | # Show first item in list
23 | print(response['Items'][0])
24 |
25 | except ClientError as error:
26 | print("Something went wrong: ")
27 | print(error.response['ResponseMetadata'])
--------------------------------------------------------------------------------
/examples/SDK/python/data_plane/WorkingWithScans/scan_simple.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function # Python 2/3 compatibility
2 | import boto3
3 | from botocore.exceptions import ClientError
4 |
5 | # Create Client
6 | session = boto3.session.Session()
7 | dynamoDbClient = session.client('dynamodb')
8 |
9 | # Table Name
10 | table_name = 'AmazonBins'
11 |
12 | try:
13 | # Scan up to 1mb of data
14 | response = dynamoDbClient.scan(
15 | TableName=table_name
16 | )
17 |
18 | # Print number of items returned
19 | print("Items Returned: {}".format(len(response['Items'])))
20 |
21 | except ClientError as error:
22 | print("Something went wrong: ")
23 | print(error.response['ResponseMetadata'])
--------------------------------------------------------------------------------
/examples/SDK/rust/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | debug/
3 | Cargo.lock
4 |
5 | .idea/
6 |
--------------------------------------------------------------------------------
/examples/SDK/rust/Operations.md:
--------------------------------------------------------------------------------
1 | # Supported Operations - Table needs to be updated
2 |
--------------------------------------------------------------------------------
/examples/SDK/rust/control_plane/working_with_tables/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_tables"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "list-tables"
15 | path = "src/list-tables/main.rs"
16 |
17 | [[bin]]
18 | name = "create-table-on-demand"
19 | path = "src/create-table-on-demand/main.rs"
20 |
21 | [[bin]]
22 | name = "describe-table"
23 | path = "src/describe-table/main.rs"
24 |
25 | [[bin]]
26 | name = "delete-table"
27 | path = "src/delete-table/main.rs"
28 |
--------------------------------------------------------------------------------
/examples/SDK/rust/control_plane/working_with_tables/src/delete-table/main.rs:
--------------------------------------------------------------------------------
1 | #[tokio::main]
2 | async fn main() -> Result<(), dynamodb::Error> {
3 | let client = dynamodb::Client::from_env();
4 | let table_name = String::from("Music");
5 |
6 | let resp = client.delete_table()
7 | .table_name(&table_name)
8 | .send().await?;
9 | println!("Table is deleted: {:?}", resp.table_description);
10 | Ok(())
11 | }
12 |
--------------------------------------------------------------------------------
/examples/SDK/rust/control_plane/working_with_tables/src/describe-table/main.rs:
--------------------------------------------------------------------------------
1 | #[tokio::main]
2 | async fn main() -> Result<(), dynamodb::Error> {
3 | let client = dynamodb::Client::from_env();
4 | let table_name = String::from("Music");
5 |
6 | let resp = client.describe_table()
7 | .table_name(&table_name)
8 | .send().await?;
9 | println!("Describe table result: {:?}", resp.table);
10 | Ok(())
11 | }
--------------------------------------------------------------------------------
/examples/SDK/rust/control_plane/working_with_tables/src/list-tables/main.rs:
--------------------------------------------------------------------------------
1 | #[tokio::main]
2 | async fn main() -> Result<(), dynamodb::Error> {
3 | let client = dynamodb::Client::from_env();
4 | let req = client.list_tables().limit(10);
5 | let resp = req.send().await?;
6 | println!("Current DynamoDB tables: {:?}", resp.table_names);
7 | Ok(())
8 | }
9 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_indexes/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_indexes"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "create-index"
15 | path = "src/create-index/main.rs"
16 |
17 | [[bin]]
18 | name = "delete-index"
19 | path = "src/delete-index/main.rs"
20 |
21 | [[bin]]
22 | name = "query-index"
23 | path = "src/query-index/main.rs"
24 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_indexes/README.md:
--------------------------------------------------------------------------------
1 | # Rust SDK examples for Amazon DynamoDB - GlobalSecondaryIndex
2 |
3 | First, create a table:
4 | ```
5 | cd ../working_with_tables
6 | cargo run --bin create-table-on-demand
7 | cd -
8 | ```
9 |
10 | Second, create an index
11 | ```
12 | cargo run --bin create-index
13 | ```
14 |
15 | Third, prepare test data for query
16 | ```
17 | cd ../working_with_queries
18 | cargo run --bin prepare-query-data
19 | cd -
20 | ```
21 |
22 | Now you can run query the GSI
23 | ```
24 | cargo run --bin query-gsi
25 | ```
26 |
27 | Finally, you can delete the GSI
28 | ```
29 | cargo run --bin delete-index
30 | ```
31 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_indexes/src/delete-index/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{DeleteGlobalSecondaryIndexAction, GlobalSecondaryIndexUpdate};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | let delete_gsi = DeleteGlobalSecondaryIndexAction::builder().index_name("AlbumIndex").build();
9 | let gsi_update = GlobalSecondaryIndexUpdate::builder().delete(delete_gsi).build();
10 |
11 | let resp = client.update_table()
12 | .global_secondary_index_updates(gsi_update)
13 | .table_name(table_name)
14 | .send()
15 | .await?;
16 |
17 | println!("Delete Index: {:?}", resp.table_description);
18 | Ok(())
19 | }
20 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_indexes/src/query-index/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 | let index_name = String::from("AlbumIndex");
8 |
9 | // query all Songs in Album#2
10 | let album2 = AttributeValue::S(String::from("Album#2"));
11 |
12 | // make a consistent query
13 | let request = client.query()
14 | .table_name(table_name)
15 | .index_name(index_name)
16 | .key_condition_expression("#pk = :pk")
17 | .expression_attribute_names("#pk", "AlbumTitle")
18 | .expression_attribute_values(":pk", album2);
19 | let resp = request.send().await?;
20 |
21 | println!("Query result: {:?}", resp);
22 | Ok(())
23 | }
24 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_items"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "put-item"
15 | path = "src/put-item/main.rs"
16 |
17 | [[bin]]
18 | name = "get-item"
19 | path = "src/get-item/main.rs"
20 |
21 | [[bin]]
22 | name = "update-item"
23 | path = "src/update-item/main.rs"
24 |
25 | [[bin]]
26 | name = "delete-item"
27 | path = "src/delete-item/main.rs"
28 |
29 | [[bin]]
30 | name = "conditional-put-item"
31 | path = "src/conditional-put-item/main.rs"
32 |
33 | [[bin]]
34 | name = "conditional-update-item"
35 | path = "src/conditional-update-item/main.rs"
36 |
37 | [[bin]]
38 | name = "batch-write"
39 | path = "src/batch-write/main.rs"
40 |
41 | [[bin]]
42 | name = "batch-get"
43 | path = "src/batch-get/main.rs"
44 |
45 | [[bin]]
46 | name = "transact-put"
47 | path = "src/transact-put/main.rs"
48 |
49 | [[bin]]
50 | name = "transact-get"
51 | path = "src/transact-get/main.rs"
52 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/batch-get/main.rs:
--------------------------------------------------------------------------------
1 | use std::collections::HashMap;
2 |
3 | use dynamodb::model::{AttributeValue, KeysAndAttributes};
4 |
5 | #[tokio::main]
6 | async fn main() -> Result<(), dynamodb::Error> {
7 | let client = dynamodb::Client::from_env();
8 |
9 | let table_name = String::from("Music");
10 |
11 | // read 2 items in a single batch get request
12 | let mut key1 = HashMap::new();
13 | key1.insert(String::from("Artist"), AttributeValue::S(String::from("No One You Know")));
14 | key1.insert(String::from("SongTitle"), AttributeValue::S(String::from("Call Me Today")));
15 |
16 | let mut key2 = HashMap::new();
17 | key2.insert(String::from("Artist"), AttributeValue::S(String::from("Acme Band")));
18 | key2.insert(String::from("SongTitle"), AttributeValue::S(String::from("Happy Day")));
19 |
20 | let keys_attributes = KeysAndAttributes::builder()
21 | .keys(key1).keys(key2)
22 | .consistent_read(true)
23 | .build();
24 |
25 | let request = client
26 | .batch_get_item()
27 | .request_items(&table_name, keys_attributes);
28 | let resp = request.send().await?;
29 |
30 | println!("Batch get items: {:?}", resp);
31 | Ok(())
32 | }
33 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/conditional-put-item/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | // put an item if it does not already exist
4 | // run this example twice to get a conditional put failure
5 | #[tokio::main]
6 | async fn main() -> Result<(), dynamodb::Error> {
7 | let client = dynamodb::Client::from_env();
8 |
9 | let table_name = String::from("Music");
10 | let artist = AttributeValue::S(String::from("No One You Know"));
11 | let song_title = AttributeValue::S(String::from("Call Me Today"));
12 | let album_title = AttributeValue::S(String::from("Somewhat Famous"));
13 | let awards = AttributeValue::N(String::from("0"));
14 | let released = AttributeValue::Bool(false);
15 |
16 | let request = client
17 | .put_item()
18 | .table_name(table_name)
19 | .item("Artist", artist)
20 | .item("SongTitle", song_title)
21 | .item("AlbumTitle", album_title)
22 | .item("Awards", awards)
23 | .item("Released", released)
24 | .condition_expression(String::from("attribute_not_exists(Artist)"));
25 |
26 | let _resp = request.send().await?;
27 |
28 | println!("Item is inserted");
29 | Ok(())
30 | }
31 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/delete-item/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{AttributeValue, ReturnValue};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 |
7 | let table_name = String::from("Music");
8 | let artist = AttributeValue::S(String::from("No One You Know")); // hash key
9 | let song_title = AttributeValue::S(String::from("Call Me Today")); // range key
10 |
11 |
12 | let request = client
13 | .delete_item()
14 | .table_name(table_name)
15 | .key("Artist", artist)
16 | .key("SongTitle", song_title)
17 | .return_values(ReturnValue::AllOld);
18 | let resp = request.send().await?;
19 |
20 | println!("Item is deleted. Deleted item: {:?}", resp.attributes);
21 | Ok(())
22 | }
23 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/get-item/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 |
7 | let table_name = String::from("Music");
8 |
9 | let artist = AttributeValue::S(String::from("No One You Know")); // hash key
10 | let song_title = AttributeValue::S(String::from("Call Me Today")); // range key
11 |
12 | let request = client.get_item()
13 | .table_name(table_name)
14 | .key("Artist", artist)
15 | .key("SongTitle", song_title)
16 | .consistent_read(true);
17 | let resp = request.send().await?;
18 |
19 | println!("Get Item: {:?}", resp.item);
20 | Ok(())
21 | }
22 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/put-item/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{AttributeValue, ReturnConsumedCapacity};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 |
7 | let table_name = String::from("Music");
8 | let artist = AttributeValue::S(String::from("No One You Know"));
9 | let song_title = AttributeValue::S(String::from("Call Me Today"));
10 | let album_title = AttributeValue::S(String::from("Somewhat Famous"));
11 | let awards = AttributeValue::N(String::from("0"));
12 | let released = AttributeValue::Bool(false);
13 |
14 | let request = client
15 | .put_item()
16 | .table_name(table_name)
17 | .item("Artist", artist)
18 | .item("SongTitle", song_title)
19 | .item("AlbumTitle", album_title)
20 | .item("Awards", awards)
21 | .item("Released", released)
22 | .return_consumed_capacity(ReturnConsumedCapacity::Total);
23 |
24 | let resp = request.send().await?;
25 |
26 | println!("Item is inserted. Consumed throughput: {:?}", resp.consumed_capacity);
27 | Ok(())
28 | }
29 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/transact-get/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{AttributeValue, Get, TransactGetItem};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 |
7 | let table_name = String::from("Music");
8 |
9 | // read 2 items in a single tx get request
10 | let get1 = Get::builder().table_name(&table_name)
11 | .key(String::from("Artist"), AttributeValue::S(String::from("No One You Know")))
12 | .key(String::from("SongTitle"), AttributeValue::S(String::from("Call Me Today")))
13 | .build();
14 | let tx_get_1 = TransactGetItem::builder().get(get1).build();
15 |
16 | let get2 = Get::builder().table_name(&table_name)
17 | .key(String::from("Artist"), AttributeValue::S(String::from("Acme Band")))
18 | .key(String::from("SongTitle"), AttributeValue::S(String::from("Happy Day")))
19 | .build();
20 | let tx_get_2 = TransactGetItem::builder().get(get2).build();
21 |
22 | let request = client
23 | .transact_get_items()
24 | .transact_items(tx_get_1)
25 | .transact_items(tx_get_2);
26 | let resp = request.send().await?;
27 |
28 | println!("Tx get items: {:?}", resp);
29 | Ok(())
30 | }
31 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_items/src/update-item/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{AttributeValue, ReturnValue};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 |
7 | let table_name = String::from("Music");
8 | let artist = AttributeValue::S(String::from("No One You Know")); // hash key
9 | let song_title = AttributeValue::S(String::from("Call Me Today")); // range key
10 |
11 | // set the "Released" flag to true and increment the "Awards" count by 1
12 | let update_expression = String::from("SET Released = :r, Awards = Awards + :a");
13 | let released = AttributeValue::Bool(true);
14 | let awards_increment = AttributeValue::N(String::from("1"));
15 |
16 | let request = client
17 | .update_item()
18 | .table_name(table_name)
19 | .key("Artist", artist)
20 | .key("SongTitle", song_title)
21 | .update_expression(update_expression)
22 | .expression_attribute_values(String::from(":r"), released)
23 | .expression_attribute_values(String::from(":a"), awards_increment)
24 | .return_values(ReturnValue::AllNew);
25 | let resp = request.send().await?;
26 |
27 | println!("Item is updated. New item: {:?}", resp.attributes);
28 | Ok(())
29 | }
30 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_queries"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "prepare-query-data"
15 | path = "src/prepare-query-data/main.rs"
16 |
17 | [[bin]]
18 | name = "query-consistent-read"
19 | path = "src/query-consistent-read/main.rs"
20 |
21 | [[bin]]
22 | name = "query-scan-filter"
23 | path = "src/query-scan-filter/main.rs"
24 |
25 | [[bin]]
26 | name = "query-projection"
27 | path = "src/query-projection/main.rs"
28 |
29 | [[bin]]
30 | name = "query-consumed-capacity"
31 | path = "src/query-consumed-capacity/main.rs"
32 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/README.md:
--------------------------------------------------------------------------------
1 | # Rust SDK examples for Amazon DynamoDB - Query API
2 |
3 | First, create a table:
4 | ```
5 | cd ../working_with_tables
6 | cargo run --bin create-table-on-demand
7 | cd -
8 | ```
9 |
10 | Second, prepare test data for query
11 | ```
12 | cargo run --bin prepare-query-data
13 | ```
14 |
15 | Then you can run the query example
16 | ```
17 | cargo run --bin query-consistent-read
18 | cargo run --bin query-scan-filter
19 | cargo run --bin query-projection
20 | ```
21 |
22 | Finally, you can delete the table
23 | ```
24 | cd ../working_with_tables
25 | cargo run --bin delete-table
26 | cd -
27 | ```
28 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/src/prepare-query-data/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | for artist_idx in 0..10 {
9 | for song_idx in 0..10 {
10 | let artist = AttributeValue::S(format!("Artist#{}", artist_idx));
11 | let song_title = AttributeValue::S(format!("Song#{}", song_idx));
12 | let album_title = AttributeValue::S(format!("Album#{}", artist_idx * song_idx));
13 |
14 | let awards = AttributeValue::N(String::from("0"));
15 | let released = AttributeValue::Bool(song_idx % 2 == 0);
16 |
17 | let request = client
18 | .put_item()
19 | .table_name(&table_name)
20 | .item("Artist", artist)
21 | .item("SongTitle", song_title)
22 | .item("AlbumTitle", album_title)
23 | .item("Awards", awards)
24 | .item("Released", released);
25 |
26 | request.send().await?;
27 | }
28 | }
29 |
30 | Ok(())
31 | }
32 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/src/query-consistent-read/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | // query all Music made by Artist#2
9 | let artist2 = AttributeValue::S(String::from("Artist#2"));
10 |
11 | // make a consistent query
12 | let request = client.query()
13 | .table_name(table_name)
14 | .key_condition_expression("#pk = :pk")
15 | .expression_attribute_names("#pk", "Artist")
16 | .expression_attribute_values(":pk", artist2)
17 | .consistent_read(true);
18 | let resp = request.send().await?;
19 |
20 | println!("Query result: {:?}", resp);
21 | Ok(())
22 | }
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/src/query-consumed-capacity/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{AttributeValue, ReturnConsumedCapacity};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | // query all Music made by Artist#2
9 | let artist2 = AttributeValue::S(String::from("Artist#2"));
10 |
11 | // make a consistent query
12 | let request = client.query()
13 | .table_name(table_name)
14 | .key_condition_expression("#pk = :pk")
15 | .expression_attribute_names("#pk", "Artist")
16 | .expression_attribute_values(":pk", artist2)
17 | .return_consumed_capacity(ReturnConsumedCapacity::Total);
18 | let resp = request.send().await?;
19 |
20 | println!("Query total consumed capacity: {:?}", resp.consumed_capacity);
21 | Ok(())
22 | }
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/src/query-projection/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | // query all Music made by Artist#2
9 | let artist2 = AttributeValue::S(String::from("Artist#2"));
10 |
11 | // query with projection
12 | let request = client.query()
13 | .table_name(table_name)
14 | .key_condition_expression("#pk = :pk")
15 | .expression_attribute_names("#pk", "Artist")
16 | .expression_attribute_values(":pk", artist2)
17 | .projection_expression("SongTitle, Awards");
18 | let resp = request.send().await?;
19 |
20 | println!("Query items: {:?}", resp.items);
21 | Ok(())
22 | }
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_queries/src/query-scan-filter/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::AttributeValue;
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | // query all released Music made by Artist#2
9 | let artist2 = AttributeValue::S(String::from("Artist#2"));
10 | let released = AttributeValue::Bool(true);
11 |
12 | // make a consistent query
13 | let request = client.query()
14 | .table_name(table_name)
15 | .key_condition_expression("#pk = :pk")
16 | .filter_expression("#r = :r")
17 | .expression_attribute_names("#pk", "Artist")
18 | .expression_attribute_values(":pk", artist2)
19 | .expression_attribute_names("#r", "Released")
20 | .expression_attribute_values(":r", released)
21 | .consistent_read(true);
22 | let resp = request.send().await?;
23 |
24 | println!("Query scanned {:?} items and returned {:?} items", resp.scanned_count, resp.count);
25 | println!("Query items: {:?}", resp.items);
26 |
27 | Ok(())
28 | }
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_scans/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_scans"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "scan-with-pagination"
15 | path = "src/scan-with-pagination/main.rs"
16 |
17 | [[bin]]
18 | name = "scan-in-parallel"
19 | path = "src/scan-in-parallel/main.rs"
20 |
21 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_scans/README.md:
--------------------------------------------------------------------------------
1 | # Rust SDK examples for Amazon DynamoDB - Scan API
2 |
3 | First, create a table:
4 | ```
5 | cd ../working_with_tables
6 | cargo run --bin create-table-on-demand
7 | cd -
8 | ```
9 |
10 | Second, prepare test data for query
11 | ```
12 | cd ../working_with_queries
13 | cargo run --bin prepare-query-data
14 | cd -
15 | ```
16 |
17 | Then you can run the scan example
18 | ```
19 | cargo run --bin scan-with-pagination
20 | cargo run --bin scan-in-parallel
21 | ```
22 |
23 | Finally, you can delete the table
24 | ```
25 | cd ../working_with_tables
26 | cargo run --bin delete-table
27 | cd -
28 | ```
29 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_scans/src/scan-in-parallel/main.rs:
--------------------------------------------------------------------------------
1 | #[tokio::main]
2 | async fn main() -> Result<(), dynamodb::Error> {
3 | let client = dynamodb::Client::from_env();
4 | let table_name = String::from("Music");
5 |
6 | // scan the table as 5 segments in parallel
7 | let segment_count = 5;
8 | let mut requests = Vec::with_capacity(segment_count);
9 | for i in 0..segment_count {
10 | let request = client.scan()
11 | .table_name(&table_name)
12 | .total_segments(segment_count as i32)
13 | .segment(i as i32).send();
14 |
15 | requests.push(request);
16 | }
17 |
18 | while !requests.is_empty() {
19 | let request = requests.pop().unwrap();
20 | let resp = request.await?;
21 | println!("Segment scan result: {:?}", resp.items);
22 | }
23 |
24 | Ok(())
25 | }
26 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_scans/src/scan-with-pagination/main.rs:
--------------------------------------------------------------------------------
1 | #[tokio::main]
2 | async fn main() -> Result<(), dynamodb::Error> {
3 | let client = dynamodb::Client::from_env();
4 | let table_name = String::from("Music");
5 |
6 | let mut last_evaluated_key = None;
7 |
8 | // scan the table 1 items at a time
9 | loop {
10 | let request = client.scan()
11 | .table_name(&table_name)
12 | .set_exclusive_start_key(last_evaluated_key)
13 | .limit(1);
14 | let resp = request.send().await?;
15 |
16 | last_evaluated_key = resp.last_evaluated_key;
17 | if last_evaluated_key.is_none() {
18 | // nothing is scanned in this iteration. we have reached the end.
19 | break;
20 | }
21 |
22 | println!("Scanned 1 item: {:?}", resp.items);
23 | }
24 |
25 | Ok(())
26 | }
27 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_streams/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "working_with_streams"
3 | version = "0.1.0"
4 | authors = ["Erben Mo "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 | [dependencies]
10 | dynamodb = { git = "https://github.com/awslabs/aws-sdk-rust", tag = "v0.0.4-alpha", package = "aws-sdk-dynamodb" }
11 | tokio = { version = "1", features = ["full"] }
12 |
13 | [[bin]]
14 | name = "enable-update-streams"
15 | path = "src/enable-update-streams/main.rs"
16 |
17 | [[bin]]
18 | name = "disable-update-streams"
19 | path = "src/disable-update-streams/main.rs"
20 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_streams/src/disable-update-streams/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{StreamSpecification, StreamViewType};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | let stream_specification = StreamSpecification::builder()
9 | .stream_enabled(false)
10 | .build();
11 |
12 | let resp = client.update_table()
13 | .table_name(table_name)
14 | .stream_specification(stream_specification)
15 | .send()
16 | .await?;
17 |
18 | println!("Disabling Update Streams: {:?}", resp.table_description);
19 | Ok(())
20 | }
21 |
--------------------------------------------------------------------------------
/examples/SDK/rust/data_plane/working_with_streams/src/enable-update-streams/main.rs:
--------------------------------------------------------------------------------
1 | use dynamodb::model::{StreamSpecification, StreamViewType};
2 |
3 | #[tokio::main]
4 | async fn main() -> Result<(), dynamodb::Error> {
5 | let client = dynamodb::Client::from_env();
6 | let table_name = String::from("Music");
7 |
8 | let stream_specification = StreamSpecification::builder()
9 | .stream_enabled(true)
10 | .stream_view_type(StreamViewType::NewAndOldImages)
11 | .build();
12 |
13 | let resp = client.update_table()
14 | .table_name(table_name)
15 | .stream_specification(stream_specification)
16 | .send()
17 | .await?;
18 |
19 | println!("Enabling Update Streams: {:?}", resp.table_description);
20 | Ok(())
21 | }
22 |
--------------------------------------------------------------------------------
/examples/hedging/java/ddb-hedging-sample/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**/target/
5 | !**/src/test/**/target/
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 | !**/src/main/**/build/
30 | !**/src/test/**/build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 | src/test/.DS_Store
35 | src/test/java/.DS_Store
36 | src/test/java/com/.DS_Store
37 | src/.DS_Store
38 | src/main/.DS_Store
39 | src/main/java/.DS_Store
40 | src/main/java/com/.DS_Store
41 | /**/.DS_Store
42 | mvnw
43 | mvnw.cmd
44 | .mvn/wrapper/maven-wrapper.jar
45 | .mvn/wrapper/maven-wrapper.properties
46 |
47 | #### Project specific #####
48 | loadtest/data/**
49 | logs/*.*
50 |
51 | *.log
52 | *.code-workspace
53 | /.gradle/
54 | /build/
55 |
56 | /.idea/
57 |
--------------------------------------------------------------------------------
/examples/hedging/java/ddb-hedging-sample/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=INFO, stdout
3 |
4 | # Direct log messages to stdout
5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6 | log4j.appender.stdout.Target=System.out
7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c - %m%n
9 |
10 | # AWS SDK logging levels
11 | log4j.logger.software.amazon.awssdk=INFO
12 | log4j.logger.software.amazon.awssdk.request=INFO
13 |
14 | # Set specific logger levels
15 | log4j.logger.com.example.dynamodbhedging.DDBHedgingRequestHandler=WARN
16 | log4j.logger.com.example.dynamodbhedging.DynamoDBHedgedQuery=INFO
17 |
--------------------------------------------------------------------------------
/infrastructure_as_code/README.md:
--------------------------------------------------------------------------------
1 | # 🗂️ Infrastructure as Code # Update me !!
2 |
3 | This folder contains templates and projects for deploying Amazon DynamoDB resources to AWS using Infrastructure as Code (IaC) tools.
4 |
5 | ## 📁 CloudFormation
6 |
7 | The cloudformation folder includes all the templates in this repository that are deployable via AWS CloudFormation. Each solution has a dedicated folder that contains a deployable CloudFormation template, along with a README.md file that explains the purpose of the template.
8 |
9 | [Explore the CloudFormation templates »](./cloudformation/README.md)
10 |
11 | ## 📁 AWS CDK
12 |
13 | The cdk folder contains AWS CDK projects, with one folder per solution that includes a deployable CDK stack. Each project has a README.md file that explains the importance of the solution, the pre-requisites, and how to deploy it.
14 |
15 | [Check out the AWS CDK examples »](./cdk/README.md)
16 |
17 | ## 📁 Security
18 |
19 | The security folder includes examples of IAM policies in JSON format that can be used to secure your DynamoDB resources. Optionally, you can find CDK and CloudFormation examples for these policies as well.
20 |
21 | [Discover the DynamoDB security policies »](./security/README.md)
22 |
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/DynamoDBCustomMetrics/README.md:
--------------------------------------------------------------------------------
1 | # Track table size and item count histories with CloudWatch
2 |
3 | Amazon DynamoDB populates many metrics about its operations to Amazon CloudWatch.
4 | At the time of this writing the list includes 33 metrics including: throughput consumed
5 | and provisioned, account and table limits, request latencies, system errors, and user errors.
6 | Two metrics not included are the DynamoDB table size and item count. These values can be
7 | observed in the AWS Web Console and retrieved via a DescribeTable API call, however the
8 | values are not persisted to CloudWatch.
9 |
10 | This repository includes source code that can be useful to track the history of these
11 | metrics, using a simple design that pushes these metrics to CloudWatch using AWS Lambda
12 | and Amazon EventBridge. The code can be deployed into your own account using AWS Cloud
13 | Development Kit (CDK). The end result is having easy access to the size and item counts
14 | of DynamoDB tables and indexes within CloudWatch.
15 |
16 | 
17 |
18 | Further instructions and explanation will be forthcoming.
19 |
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/DynamoDBCustomMetrics/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "python3 app.py",
3 | "watch": {
4 | "include": [
5 | "**"
6 | ],
7 | "exclude": [
8 | "README.md",
9 | "cdk*.json",
10 | "requirements*.txt",
11 | "source.bat",
12 | "**/__init__.py",
13 | "python/__pycache__",
14 | "tests"
15 | ]
16 | },
17 | "context": {
18 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
19 | "@aws-cdk/core:stackRelativeExports": true,
20 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
21 | "@aws-cdk/aws-lambda:recognizeVersionProps": true,
22 | "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
23 | "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
24 | "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25 | "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26 | "@aws-cdk/core:checkSecretUsage": true,
27 | "@aws-cdk/aws-iam:minimizePolicies": true,
28 | "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29 | "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30 | "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31 | "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32 | "@aws-cdk/core:target-partitions": [
33 | "aws",
34 | "aws-cn"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/DynamoDBCustomMetrics/dynamodb_custom_metrics/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/infrastructure_as_code/cdk/DynamoDBCustomMetrics/dynamodb_custom_metrics/__init__.py
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/DynamoDBCustomMetrics/requirements.txt:
--------------------------------------------------------------------------------
1 | aws-cdk-lib==2.34.2
2 | constructs>=10.0.0,<11.0.0
3 |
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/DynamoDBCustomMetrics/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/infrastructure_as_code/cdk/DynamoDBCustomMetrics/screenshot.png
--------------------------------------------------------------------------------
/infrastructure_as_code/cdk/README.md:
--------------------------------------------------------------------------------
1 | # 📁 AWS CDK Projects
2 |
3 | ## 📂 DynamoDBCustomMetrics
4 |
5 | This CDK project publishes to CloudWatch two important metrics - table size and item count - that are not automatically pushed to CloudWatch. The [DynamoDBCustomMetrics](./DynamoDBCustomMetrics/README.md) project solves this by using AWS Lambda and Amazon EventBridge to capture and report these missing metrics to CloudWatch. This enables you to:
6 |
7 | - Monitor Table Growth: Gain visibility into the size and item count of your DynamoDB tables over time, helping you identify potential performance issues.
8 | - Optimize Provisioning: Use the collected metrics to set up alerts and auto-scaling policies, ensuring your DynamoDB tables are optimally provisioned.
9 | - Analyze Trends: Explore historical data on your table's growth, informing your capacity planning and optimization efforts.
10 |
--------------------------------------------------------------------------------
/infrastructure_as_code/cloudformation/global_tables/GlobalTable_OnDemand.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: 2010-09-09
2 | Resources:
3 | MyGlobalTable:
4 | Type: 'AWS::DynamoDB::GlobalTable'
5 | Properties:
6 | AttributeDefinitions:
7 | - AttributeName: PK
8 | AttributeType: S
9 | - AttributeName: SK
10 | AttributeType: S
11 | - AttributeName: GSI1PK
12 | AttributeType: S
13 | - AttributeName: GSI1SK
14 | AttributeType: S
15 | BillingMode: PAY_PER_REQUEST
16 | GlobalSecondaryIndexes:
17 | - IndexName: GSI1
18 | KeySchema:
19 | - AttributeName: GSI1PK
20 | KeyType: HASH
21 | - AttributeName: GSI1SK
22 | KeyType: RANGE
23 | Projection:
24 | ProjectionType: ALL
25 | KeySchema:
26 | - AttributeName: PK
27 | KeyType: HASH
28 | - AttributeName: SK
29 | KeyType: RANGE
30 | Replicas:
31 | - Region: eu-west-1
32 | - Region: eu-west-2
33 | TableName: MyGT
34 | StreamSpecification:
35 | StreamViewType: NEW_AND_OLD_IMAGES
--------------------------------------------------------------------------------
/infrastructure_as_code/cloudformation/global_tables/README.md:
--------------------------------------------------------------------------------
1 | # Global Tables
2 |
--------------------------------------------------------------------------------
/infrastructure_as_code/security/DynamoDBIAMPolicies/AmazonDynamoDBAcceleratorDataFullAccess.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "AmazonDynamoDBDAXDataOperations",
6 | "Effect": "Allow",
7 | "Action": [
8 | "dax:GetItem",
9 | "dax:PutItem",
10 | "dax:ConditionCheckItem",
11 | "dax:BatchGetItem",
12 | "dax:BatchWriteItem",
13 | "dax:DeleteItem",
14 | "dax:Query",
15 | "dax:UpdateItem",
16 | "dax:Scan"
17 | ],
18 | "Resource": "arn:aws:dax:${AWS::Region}:${AWS::AccountId}:cache/*"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/infrastructure_as_code/security/DynamoDBIAMPolicies/AmazonDynamoDBStreamsOnlyAccess.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Sid": "AccessStreamOnly",
6 | "Effect": "Allow",
7 | "Action": [
8 | "dynamodb:DescribeStream",
9 | "dynamodb:GetRecords",
10 | "dynamodb:GetShardIterator",
11 | "dynamodb:ListStreams"
12 | ],
13 | "Resource": "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${DDB::TableName}/stream/*"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/schema_design/BuildingBlocks/WriteSharding/README.md:
--------------------------------------------------------------------------------
1 | # Write Sharding
2 | One way to better distribute writes across a partition key space in Amazon DynamoDB is to expand the space. You can do this in several different ways. You can add a random number to the partition key values to distribute the items among partitions. Or you can use a number that is calculated based on something that you're querying on.
3 |
4 | ## Examples
5 | Code examples provided demonstrate writing and reading from a DynamoDB table using write sharding.
6 |
7 | ## Run it
8 | Python: The script requires you have Python3 and installed modules: boto3, json, and random.
9 |
10 | DynamoDB: Create a table called "ExampleTable" with a partition key of "pk" and a sort key of "sk". Change the AWS Region to your closest.
11 |
12 | % python3 WriteShardingExample.py
13 |
14 | ## Disclaimer
15 | Provided as a sample. The script assumes the runtime has an AWS account with appropriate permissions.
16 |
17 | ## Contribute
18 | Be the first to enhance this code with a Pull Request.
19 |
--------------------------------------------------------------------------------
/schema_design/SchemaExamples/ConnectedVehicles/README.md:
--------------------------------------------------------------------------------
1 | # Connected Vehicles Data Modeling with Amazon DynamoDB
2 |
3 | ## Overview
4 |
5 | This document outlines a detailed data modeling and schema design approach for a "Connected Vehicles" use case using Amazon DynamoDB. The model supports a system where vehicle manufacturers can offer various features and functionalities as subscriptions for users to enable.
6 |
7 | ## Key Entities
8 |
9 | 1. Vehicle
10 | 2. Features
11 | 3. User (Customer)
12 | 4. Preferences
13 |
14 | ## Design Approach
15 |
16 | We employ a single table design with the following key structure:
17 |
18 | - Partition Key (PK): Identifies the entity type (e.g., VIN# for vehicles, ID# for users)
19 | - Sort Key (SK): Organizes data within each entity
20 |
21 | ## Access Patterns
22 |
23 | The document covers 22 key access patterns, including but not limited to:
24 |
25 | - Creating and retrieving vehicles
26 | - Managing user preferences
27 | - Linking users to vehicles
28 | - Managing subscriptions
29 |
30 | For each access pattern, we provide:
31 | - Specific PK and SK used
32 | - Relevant DynamoDB operations (PutItem, Query, UpdateItem, DeleteItem, BatchWriteItem)
33 |
34 | ## Goals
35 |
36 | - Model relationships between vehicles, features, and user preferences efficiently
37 | - Ensure scalability using Amazon DynamoDB's single table design principles
38 |
39 | ## Schema Design
40 |
41 | A comprehensive schema design is included, demonstrating how different entities and access patterns map to the DynamoDB table structure.
42 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/LoadMaxValues/java/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use an official Java base image
2 | FROM openjdk:11
3 |
4 | # Set the working directory
5 | WORKDIR /app
6 |
7 | # Copy your pom.xml and LoadMaxValues.java file into the container
8 | COPY pom.xml .
9 | COPY src/ ./src/
10 |
11 | # Install Maven
12 | RUN apt-get update && \
13 | apt-get install -y maven
14 |
15 | # Build the Java application
16 | RUN mvn clean install
17 |
18 | # Set the entry point for the container
19 | ENTRYPOINT ["sh", "-c", "java -jar target/LoadMaxValues-1.0-SNAPSHOT.jar"]
20 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/LoadMaxValues/java/README.md:
--------------------------------------------------------------------------------
1 | # CLI Parameters
2 |
3 | The LaodMaxValues class accepts --region as a required parameter, or you can
4 | pass in environment variables for the AWS_DEFAULT_REGION as is done with docker below.
5 |
6 | # How to build and run using docker
7 |
8 | docker build -t load-max-values .
9 |
10 | docker run --rm -it \
11 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
12 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
13 | -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \
14 | load-max-values
15 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/LoadMaxValues/nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dynamodb-load-max-sk-value",
3 | "version": "1.0.0",
4 | "description": "A simple script to test the loading of a maximum sort key value",
5 | "main": "loadMaxValues.js",
6 | "dependencies": {
7 | "@aws-sdk/client-dynamodb": "^3.293.0",
8 | "commander": "^10.0.0"
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/Printer/java/Dockerfile:
--------------------------------------------------------------------------------
1 | # Use an official Java base image
2 | FROM openjdk:11
3 |
4 | # Set the working directory
5 | WORKDIR /app
6 |
7 | # Copy your pom.xml and PrintDistinctPKs.java file into the container
8 | COPY pom.xml .
9 | COPY src/ ./src/
10 |
11 | # Install Maven
12 | RUN apt-get update && \
13 | apt-get install -y maven
14 |
15 | # Build the Java application
16 | RUN mvn clean install
17 |
18 | # Set the entry point for the container
19 | ENTRYPOINT ["sh", "-c", "java -jar target/PrintDistinctPKs-1.0-SNAPSHOT.jar"]
20 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/Printer/java/README.md:
--------------------------------------------------------------------------------
1 | # CLI Parameters
2 |
3 | The LaodMaxValues class accepts --region and
4 | --table-name as a parameter, or you can pass in environment
5 | variables for the AWS_DEFAULT_REGION as is done with docker below.
6 |
7 | # How to build and run using docker
8 |
9 | docker build -t print-distinct-pks .
10 |
11 | docker run --rm -it \
12 | -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \
13 | -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \
14 | -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \
15 | -e DYNAMODB_TABLE_NAME=my-table-name \
16 | print-distinct-pks
17 |
18 | docker rmi -f print-distinct-pks
19 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/Printer/nodejs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dynamodb-print-distinct-pks",
3 | "version": "1.0.0",
4 | "description": "A simple script to show an optimal method for printing a distinct list of Primary Keys in a DynamoDB Table",
5 | "main": "print_distinct_pks.js",
6 | "dependencies": {
7 | "@aws-sdk/client-dynamodb": "^3.293.0",
8 | "commander": "^10.0.0"
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/scripts/PrintDistinctPKs/README.md:
--------------------------------------------------------------------------------
1 | # Update Me!
2 |
--------------------------------------------------------------------------------
/scripts/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | services:
4 | dynamodb-local:
5 | image: amazon/dynamodb-local
6 | container_name: dynamodb-local
7 | ports:
8 | - "8000:8000"
9 | app-node:
10 | depends_on:
11 | - dynamodb-local
12 | image: amazon/aws-cli
13 | container_name: app-node
14 | ports:
15 | - "8080:8080"
16 | environment:
17 | AWS_ACCESS_KEY_ID: 'DUMMYIDEXAMPLE'
18 | AWS_SECRET_ACCESS_KEY: 'DUMMYEXAMPLEKEY'
19 | command:
20 | dynamodb describe-limits --endpoint-url http://dynamodb-local:8000 --region us-west-2
21 |
--------------------------------------------------------------------------------
/workshops/README.md:
--------------------------------------------------------------------------------
1 | # 🗓️ Workshops
2 |
3 | The workshops folder temporarily stores workshop content and materials that can be used to learn how to use Amazon DynamoDB in real-life applications. These workshops are designed to provide hands-on experience and guide you through the process of building DynamoDB-powered solutions.
4 |
5 | ## 🌟 Hands-On Learning
6 |
7 | The workshops in this folder cover a wide range of topics, from DynamoDB fundamentals to advanced use cases. Each workshop includes:
8 |
9 | Comprehensive Instructions: Detailed step-by-step guides that walk you through the workshop exercises.
10 | Sample Code and Resources: Supporting code samples, configuration files, and other resources needed to complete the workshops.
11 | Real-world Scenarios: The workshops focus on practical, real-world applications of DynamoDB, helping you develop skills that are directly applicable to your own projects.
12 |
13 | ## 📚 Explore the Workshops
14 |
15 | Whether you're new to DynamoDB or looking to expand your expertise, these workshops provide an invaluable learning experience. Browse the available workshops and choose the ones that align with your specific goals and interests.
16 |
17 | Check out the DynamoDB workshops »
18 |
19 | - [Global serverless workshop](./global-serverless/README.md)
20 | - [Relational to DynamoDB migration workshop](./relational-migration/README.md)
21 |
--------------------------------------------------------------------------------
/workshops/global-serverless/.chalice/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0",
3 | "app_name": "global-serverless",
4 | "stages": {
5 | "dev": {
6 | "api_gateway_stage": "api"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/workshops/global-serverless/README.md:
--------------------------------------------------------------------------------
1 | ## Global Serverless workshop 🌎 🌍 🌏
2 |
3 | Welcome! This workshop will show you how to use DynamoDB Global Tables as the
4 | foundation for a resilient multi-region serverless application.
5 |
6 | For the full instructions please follow this link to [Amazon Workshop Studio](https://catalog.us-east-1.prod.workshops.aws/workshops/eb85cafa-2060-4524-9e70-20c2987ca378)
--------------------------------------------------------------------------------
/workshops/global-serverless/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | chalice==1.27.3
2 | pytest
3 |
--------------------------------------------------------------------------------
/workshops/global-serverless/requirements.txt:
--------------------------------------------------------------------------------
1 | boto3
2 | chalice
3 |
--------------------------------------------------------------------------------
/workshops/global-serverless/s3.sh:
--------------------------------------------------------------------------------
1 | aws s3 sync web/ s3://dynamodbworkshop/global-serverless/
2 |
--------------------------------------------------------------------------------
/workshops/global-serverless/test.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 |
5 | testpath = '/scan'
6 | testpath = '/query/user100'
7 | testpath = '/get/user100/AshlandValley'
8 | # testpath = '/update/user100/AshlandValley/-3'
9 |
10 |
11 | def test_index():
12 | with Client(app) as client:
13 | response = client.http.get(testpath)
14 | print()
15 | print(json.dumps(response.json_body))
16 |
17 |
18 | test_index()
19 |
--------------------------------------------------------------------------------
/workshops/global-serverless/web/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/workshops/global-serverless/web/favicon.ico
--------------------------------------------------------------------------------
/workshops/global-serverless/web/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-dynamodb-examples/aa1021683269d0abbccb091022e02fdf1f94a4b7/workshops/global-serverless/web/logo.png
--------------------------------------------------------------------------------
/workshops/relational-migration/.chalice/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0",
3 | "app_name": "migration",
4 | "stages": {
5 |
6 | "relational": {
7 | "api_gateway_stage": "relational",
8 | "environment_variables": {
9 | "MYSQL_HOST": "##DBHOST##",
10 | "MYSQL_DB": "app_db",
11 | "MYSQL_USERNAME": "##DBUSERNAME##",
12 | "MYSQL_PASSWORD": "##DBPASSWORD##",
13 | "MIGRATION_STAGE": "relational"
14 | },
15 | "autogen_policy": false,
16 | "iam_policy_file": "relational-migration-policy.json",
17 | "subnet_ids": ["##SUBNETID##"],
18 | "security_group_ids": ["##SECURITYGROUPID##"]
19 | },
20 | "dynamodb": {
21 | "api_gateway_stage": "dynamodb",
22 | "environment_variables": {
23 | "MIGRATION_STAGE": "dynamodb"
24 | },
25 | "autogen_policy": false,
26 | "iam_policy_file": "relational-migration-policy.json"
27 | }
28 |
29 | }
30 | }
--------------------------------------------------------------------------------
/workshops/relational-migration/README.md:
--------------------------------------------------------------------------------
1 | # Relational Database to DynamoDB Migration: Workshop Artifacts
2 |
3 | ## Contents
4 | Here you will find migration scripts, and a web application that helps you discover and convert
5 | your MySQL database data during a migration to DynamoDB.
6 |
7 | ## Instructions
8 | This project accompanies the LSQL: Relational Database Migration Workshop module
9 | published within [catalog.workshops.aws](https://catalog.workshops.aws/)
10 |
11 | ## Support
12 | The contents of this repository are maintained by Amazon DynamoDB Specialist solution architects
13 | and are not officially supported by AWS.
14 | Please file a [Github Issue](https://github.com/aws-samples/aws-dynamodb-examples/issues)
15 | if you experience any problems.
16 |
--------------------------------------------------------------------------------
/workshops/relational-migration/chalicelib/__init__.py:
--------------------------------------------------------------------------------
1 | MESSAGE = 'Hello Chalice'
2 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/Ledger.py:
--------------------------------------------------------------------------------
1 | import string
2 | import datetime
3 | import math
4 | import random
5 | random.seed(9)
6 |
7 | def row_maker(tick):
8 |
9 | lines_per_customer = 10
10 |
11 | cust_id = ''
12 | event_id = ''
13 |
14 | cust_id = str(math.floor(((tick+3)/lines_per_customer))).rjust(4, '0')
15 |
16 | event_id = str(((tick+3)%lines_per_customer)+1).rjust(4, '0')
17 |
18 | prod_id = str(random.randrange(1, 13)).rjust(4, '0')
19 |
20 | datedelta = -1 * random.randrange(1, 365)
21 | event_date = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta + 3))
22 |
23 | row = {
24 | 'cust_id': str(ord_id),
25 | 'event_id': ord_line_id,
26 | 'event_date': event_date
27 | 'account': '1000',
28 | 'prod_id': prod_id,
29 | 'credit': random.randrange(-50,100),
30 | 'item_price': random.randrange(400, 7000, 100),
31 |
32 | }
33 |
34 | return row
35 |
36 |
37 | start_date = '12/19/2024'
38 |
39 |
40 | def job_info():
41 | job_params = {
42 | 'db': 'mysql',
43 | 'table': 'app_db.Ledger',
44 | 'row_count': 200,
45 | }
46 | return job_params
47 |
48 |
49 | def random_string(length=8):
50 | letters = string.ascii_letters
51 | return ''.join(random.choice(letters) for i in range(length)).lower()
52 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/OrderLines.py:
--------------------------------------------------------------------------------
1 | import string
2 | import datetime
3 | import math
4 | import random
5 | random.seed(9)
6 |
7 | def row_maker(tick):
8 |
9 | lines_per_order = 4
10 |
11 | ord_id = str(math.floor(((tick+3)/lines_per_order))).rjust(4, '0')
12 |
13 | ord_line_id = str(((tick+3)%lines_per_order)+1).rjust(4, '0')
14 |
15 | prod_id = str(random.randrange(1, 13)).rjust(4, '0')
16 |
17 | datedelta = -1 * random.randrange(1, 365)
18 | last_updated = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta + 3))
19 |
20 | row = {
21 | 'ord_id': str(ord_id),
22 | 'ord_line_id': ord_line_id,
23 | 'prod_id': prod_id,
24 | 'qty': random.randrange(1,10),
25 | 'item_price': random.randrange(400, 7000, 100),
26 | 'last_updated': last_updated
27 | }
28 |
29 | return row
30 |
31 |
32 | start_date = '06/19/2024'
33 |
34 |
35 | def job_info():
36 | job_params = {
37 | 'db': 'mysql',
38 | 'table': 'app_db.OrderLines',
39 | 'row_count': 20,
40 | }
41 | return job_params
42 |
43 |
44 | def random_string(length=8):
45 | letters = string.ascii_letters
46 | return ''.join(random.choice(letters) for i in range(length)).lower()
47 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/Orders.py:
--------------------------------------------------------------------------------
1 | import string
2 | import datetime
3 | import random
4 | random.seed(11)
5 |
6 | def row_maker(tick):
7 |
8 | pk = str(tick).rjust(4, '0')
9 |
10 | datedelta = -1 * random.randrange(1, 365)
11 | ord_date = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta))
12 | ship_date = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta + 2))
13 | last_updated = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta + 3))
14 |
15 | row = {
16 | 'ord_id': str(pk),
17 | 'cust_id': str(random.randrange(1, 8)).rjust(4, '0'),
18 | 'rep_id': random.choice(reps),
19 | 'ord_date': ord_date,
20 | 'ship_date': ship_date,
21 | 'last_updated': last_updated
22 | }
23 |
24 | return row
25 |
26 |
27 | start_date = '06/19/2024'
28 | reps = ['SAM', 'PAT', 'ANA', 'LEA', 'BOB', 'ZOE']
29 |
30 | def job_info():
31 | job_params = {
32 | 'db': 'mysql',
33 | 'table': 'app_db.Orders',
34 | 'row_count': 10,
35 | }
36 | return job_params
37 |
38 |
39 | def random_string(length=8):
40 | letters = string.ascii_letters
41 | return ''.join(random.choice(letters) for i in range(length)).lower()
42 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/Products.py:
--------------------------------------------------------------------------------
1 | import string
2 | import random
3 | from datetime import datetime
4 | from datetime import timedelta
5 | random.seed(9)
6 |
7 | def row_maker(tick):
8 |
9 | pk = str(tick).rjust(4, '0')
10 |
11 | date_default = datetime(2025, 1, 1)
12 | date_offset = random.randrange(0, 100) - 50
13 | event_date = date_default + timedelta(days=date_offset)
14 |
15 | row = {
16 | 'prod_id': pk,
17 | 'name': products[tick-1],
18 | 'category': categories[tick-1],
19 | 'list_price': random.randrange(500, 8000, 100)-1,
20 | 'last_updated': event_date.isoformat()
21 | }
22 |
23 | return row
24 |
25 |
26 | def job_info():
27 | job_params = {
28 | 'db': 'mysql',
29 | 'table': 'app_db.Products',
30 | 'row_count': 14,
31 | }
32 | return job_params
33 |
34 | categories = ['Street', 'Street', 'Street', 'Street', 'Street', 'Street', 'Street', 'Snow', 'Snow', 'Air', 'Air', 'Sea', 'Lake', 'Lake', 'Sea']
35 |
36 | products = ['Bicycle', 'Car', 'Truck', 'Motorcycle', 'Moped', 'Scooter', 'Skateboard', 'Snowboard', 'Sled', 'Helicopter', 'Drone', 'Jet Ski', 'Kayak', 'Canoe', 'Motor Boat']
37 |
38 | def random_string(length=8):
39 | letters = string.ascii_letters
40 | return ''.join(random.choice(letters) for i in range(length))
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/Reps.py:
--------------------------------------------------------------------------------
1 | import string
2 | import datetime
3 | import random
4 | random.seed(10)
5 |
6 | reps = ['SAM', 'PAT', 'ANA', 'LEA', 'BOB', 'ZOE']
7 | lnames = ['DAVIS', 'SMITH', 'PATEL', 'LEE', 'ORTIZ', 'BROWN']
8 |
9 | def row_maker(tick):
10 |
11 | start_date = '06/19/2024'
12 | datedelta = -1 * random.randrange(1, 365)
13 | last_updated = str(datetime.datetime.strptime(start_date, '%m/%d/%Y') + datetime.timedelta(days=datedelta + 3))
14 |
15 | row = {
16 | 'rep_id': reps[tick-1],
17 | 'rep_name': reps[tick-1] + ' ' + lnames[tick-1],
18 | 'last_updated': last_updated
19 | }
20 |
21 | return row
22 |
23 |
24 | def job_info():
25 | job_params = {
26 | 'db': 'mysql',
27 | 'table': 'app_db.Reps',
28 | 'row_count': 6,
29 | }
30 | return job_params
31 |
32 |
33 | def random_string(length=8):
34 | letters = string.ascii_letters
35 | return ''.join(random.choice(letters) for i in range(length)).lower()
36 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/jobs/job1.py:
--------------------------------------------------------------------------------
1 |
2 | def row_maker(tick):
3 |
4 | pk = 'cust-' + str(tick).rjust(4, '0')
5 |
6 | row = {
7 | 'PK': pk,
8 | 'SK': '2024-03-30',
9 | 'city': 'Stonehamm',
10 | 'rating': tick * 10
11 | }
12 |
13 | return row
14 |
15 |
16 | def job_info():
17 | job_params = {
18 | 'db': 'dynamodb',
19 | 'table': 'Customers',
20 | 'row_count': 7
21 | }
22 | return job_params
23 |
--------------------------------------------------------------------------------
/workshops/relational-migration/load/test.py:
--------------------------------------------------------------------------------
1 | import boto3
2 | from botocore.config import Config
3 | from botocore.exceptions import ClientError
4 | import mysql.connector
5 | from datetime import datetime, timedelta
6 | import sys
7 | import importlib
8 |
9 | mysql_host = ""
10 | mysql_db = "app_db"
11 | mysql_username = "dbuser"
12 | mysql_password = ""
13 |
14 | if "MYSQL_HOST" in os.environ:
15 | mysql_host = os.environ['MYSQL_HOST']
16 | if "MYSQL_DB" in os.environ:
17 | mysql_db = os.environ['MYSQL_DB']
18 | if "MYSQL_USERNAME" in os.environ:
19 | mysql_username = os.environ['MYSQL_USERNAME']
20 | if "MYSQL_PASSWORD" in os.environ:
21 | mysql_password = os.environ['MYSQL_PASSWORD']
22 |
23 |
24 | def main(dynamodb=None, mysql_conn=None):
25 |
26 | ddb_table=None
27 | mysql_conn=None
28 | mysql_cur=None
29 |
30 | mysql_conn = mysql.connector.connect(
31 | database=mysql_db,
32 | user=mysql_username,
33 | password=mysql_password,
34 | host=mysql_host
35 | )
36 | mysql_cur = mysql_conn.cursor(buffered=True, dictionary=True)
37 | mysql_cur.execute("SELECT cust_id, name, credit_rating FROM Customers")
38 | result = mysql_cur.fetchall()
39 |
40 | for x in result:
41 | print(x)
42 |
43 | mysql_cur.close()
44 | mysql_conn.close()
45 |
46 |
47 | if __name__ == "__main__":
48 | main()
49 |
--------------------------------------------------------------------------------
/workshops/relational-migration/migrate.sh:
--------------------------------------------------------------------------------
1 | TABLE="Customers"
2 | REGION=$AWS_DEFAULT_REGION
3 |
4 | if [ $# -gt 0 ]
5 | then
6 | TABLE=$1
7 | fi
8 |
9 | KEYS_NEEDED=2
10 |
11 | if [ $# -gt 1 ]
12 | then
13 | KEYS_NEEDED=$2
14 | fi
15 |
16 | if [[ "dynamodb" = $MIGRATION_STAGE ]]
17 | then
18 | echo
19 | echo Error: run this in a shell with MIGRATION_STAGE="relational"
20 | echo
21 | exit 1
22 | fi
23 |
24 | python3 mysql_desc_ddb.py $TABLE $KEYS_NEEDED > target-tables/$TABLE.json
25 |
26 | BUCKET=$MIGRATION_BUCKET
27 | FOLDER="migrations/$TABLE/"
28 |
29 | echo Migrating into table $TABLE using S3 $BUCKET/$FOLDER
30 |
31 | # aws s3 rm s3://$BUCKET/$FOLDER --recursive
32 |
33 | printf "\n"
34 |
35 | python3 mysql_s3.py $TABLE
36 |
37 | aws dynamodb import-table \
38 | --s3-bucket-source S3Bucket=$BUCKET,S3KeyPrefix=$FOLDER \
39 | --region $REGION \
40 | --input-format DYNAMODB_JSON \
41 | --output json --query '{"Import ":ImportTableDescription.ImportArn, "Status ":ImportTableDescription.ImportStatus }' \
42 | --table-creation-parameters file://target-tables/$TABLE.json
43 |
44 | echo Table: $TABLE will be ready soon
45 |
46 | #aws dynamodb describe-import \
47 | # --import-arn 'arn:aws:dynamodb:us-west-2:889485041841:table/Customers/import/01719173281483-c35ac611' \
48 | # --output json --query '{"Status ":ImportTableDescription.ImportStatus, "FailureCode ":ImportTableDescription.FailureCode, "FailureMessage ":ImportTableDescription.FailureMessage }'
49 | #
50 |
51 |
--------------------------------------------------------------------------------
/workshops/relational-migration/requirements.txt:
--------------------------------------------------------------------------------
1 | chalice
2 | boto3
3 | mysql-connector-python
4 |
--------------------------------------------------------------------------------
/workshops/relational-migration/setup_tables.sh:
--------------------------------------------------------------------------------
1 | clear
2 | echo Creating sample SQL tables and loading data
3 | echo ..connecting to ${MYSQL_HOST}
4 | mysql -h ${MYSQL_HOST} -u ${MYSQL_USERNAME} -p${MYSQL_PASSWORD} < ./source-tables/create_tables.sql
5 | mysql -h ${MYSQL_HOST} -u ${MYSQL_USERNAME} -p${MYSQL_PASSWORD} < ./source-tables/create_views.sql
6 | cd load
7 | python3 load.py Products.py
8 | python3 load.py Customers.py
9 | python3 load.py Reps.py
10 | python3 load.py Orders.py
11 | python3 load.py OrderLines.py
12 | cd ..
13 |
--------------------------------------------------------------------------------
/workshops/relational-migration/source-tables/create_tables.sh:
--------------------------------------------------------------------------------
1 | mysqlsh --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD} --host=${MYSQL_HOST} < create_tables.sql
--------------------------------------------------------------------------------
/workshops/relational-migration/target-tables/list_imports.sh:
--------------------------------------------------------------------------------
1 | aws dynamodb list-imports \
2 | --output json \
3 | --query '{
4 | "Import ": ImportSummaryList[].ImportArn,
5 | "Status": ImportSummaryList[].ImportStatus,
6 | "StartTime": ImportSummaryList[].StartTime,
7 | "EndTime": ImportSummaryList[].EndTime
8 | }'
9 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_delete.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 | import sys
6 |
7 | testpath = '/delete_record/Customers'
8 |
9 | post_data = {'Key': {'cust_id': 'c227' }}
10 |
11 | if len(sys.argv) > 1:
12 | post_data['cust_id'] = sys.argv[1]
13 |
14 | # if len(sys.argv) > 2:
15 | # post_data['ord_line_id'] = sys.argv[2]
16 |
17 | def test_index():
18 | with Client(app) as client:
19 | response = client.http.post(
20 | testpath,
21 | headers={'Content-Type':'application/json'},
22 | body=json.dumps(post_data)
23 | )
24 | print('\ntest result')
25 | print(json.dumps(response.json_body, indent=2, default=str))
26 |
27 |
28 | test_index()
29 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_desc.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import os
5 |
6 | table_name = 'Orders'
7 | testpath = '/desc_table/' + table_name
8 |
9 |
10 | def test_index():
11 | with Client(app) as client:
12 |
13 | response = client.http.get(testpath)
14 |
15 | print(json.dumps(response.json_body, indent=2))
16 |
17 |
18 | test_index()
19 |
20 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_get.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 |
6 | testpath = '/'
7 |
8 | testpath = '/get_record/Customers'
9 |
10 | cust_id = '0003'
11 |
12 | post_data = {
13 | 'Key': {
14 | 'cust_id': cust_id
15 | }
16 | }
17 |
18 |
19 | def test_index():
20 | with Client(app) as client:
21 | response = client.http.post(
22 | testpath,
23 | headers={'Content-Type':'application/json'},
24 | body=json.dumps(post_data)
25 | )
26 |
27 | print(json.dumps(response.json_body, indent=2))
28 |
29 |
30 | test_index()
--------------------------------------------------------------------------------
/workshops/relational-migration/test_query.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 |
6 | testpath = '/'
7 |
8 | testpath = '/query/Products'
9 | category = 'Street'
10 | # last_updated = '2024*'
11 | index = 'idx_category'
12 |
13 |
14 | post_data = {
15 | 'queryRequest': {
16 | 'index': index,
17 | 'queryConditions': {
18 | 'category': category
19 | }
20 | }
21 | }
22 |
23 |
24 | def test_index():
25 | with Client(app) as client:
26 | response = client.http.post(
27 | testpath,
28 | headers={'Content-Type':'application/json'},
29 | body=json.dumps(post_data)
30 | )
31 |
32 | print(json.dumps(response.json_body, indent=2))
33 |
34 |
35 | test_index()
--------------------------------------------------------------------------------
/workshops/relational-migration/test_read.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import os
5 |
6 | testpath = '/scan_table/Products'
7 |
8 |
9 | def test_index():
10 | with Client(app) as client:
11 |
12 | response = client.http.get(testpath)
13 | # headers = {"Content-Type": "application/json"})
14 | print()
15 | print(json.dumps(response.json_body, indent=2))
16 |
17 |
18 | test_index()
19 |
20 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_scan.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import os
5 |
6 | testpath = '/scan_table/OrderLines'
7 |
8 |
9 | def test_index():
10 | with Client(app) as client:
11 |
12 | response = client.http.get(testpath)
13 | # headers = {"Content-Type": "application/json"})
14 | print()
15 | print(json.dumps(response.json_body, indent=2))
16 |
17 |
18 | test_index()
19 |
20 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_sql.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 |
6 | testpath = '/runsql'
7 |
8 | sql = 'SELECT prod_id, name, category, list_price, last_updated FROM Products LIMIT 3'
9 |
10 | # sql = 'UPDATE Products SET list_price = list_price + 1 WHERE prod_id = "0001"'
11 |
12 | sql = 'CREATE OR REPLACE VIEW vTest AS SELECT * FROM Products LIMIT 2'
13 |
14 | post_data = {
15 | 'sql':sql
16 | }
17 |
18 |
19 | def test_index():
20 | with Client(app) as client:
21 | response = client.http.post(
22 | testpath,
23 | headers={'Content-Type':'application/json'},
24 | body=json.dumps(post_data)
25 | )
26 |
27 | print(json.dumps(response.json_body, indent=2))
28 |
29 |
30 | test_index()
--------------------------------------------------------------------------------
/workshops/relational-migration/test_tables.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import os
5 |
6 | testpath = '/list_tables/'
7 |
8 |
9 | def test_index():
10 | with Client(app) as client:
11 |
12 | response = client.http.get(testpath)
13 |
14 | print(json.dumps(response.json_body, indent=2))
15 |
16 |
17 | test_index()
18 |
19 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_update.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 |
6 | testpath = '/update_record/Customers'
7 |
8 | cust_id = 'c223'
9 |
10 | post_data = {
11 | 'Key': {
12 | 'cust_id': cust_id
13 | },
14 | 'updateAttributes' : {
15 | 'email': 'admin@bcect.edu',
16 | 'region': 'Northerneey',
17 | 'credit_rating': 122.3,
18 | 'last_updated': '2024-06-18'
19 | }
20 | }
21 |
22 | def test_index():
23 | with Client(app) as client:
24 | response = client.http.post(
25 | testpath,
26 | headers={'Content-Type':'application/json'},
27 | body=json.dumps(post_data)
28 | )
29 |
30 | print(json.dumps(response.json_body, indent=2))
31 |
32 |
33 | test_index()
--------------------------------------------------------------------------------
/workshops/relational-migration/test_view.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import os, sys
5 |
6 | view_name = 'vCustOrders'
7 |
8 | if len(sys.argv) > 1:
9 | view_name = sys.argv[1]
10 |
11 | testpath = '/desc_view/' + view_name
12 |
13 | def test_index():
14 | with Client(app) as client:
15 |
16 | response = client.http.get(testpath)
17 | view_definition = response.json_body.get('VIEW_DEFINITION', 'None')
18 | print(view_definition)
19 | print()
20 |
21 | test_index()
22 |
23 |
--------------------------------------------------------------------------------
/workshops/relational-migration/test_write.py:
--------------------------------------------------------------------------------
1 | from chalice.test import Client
2 | from app import app
3 | import json
4 | import time
5 |
6 | testpath = '/'
7 |
8 | # testpath = '/scan'
9 | # testpath = '/list_customers'
10 | testpath = '/new_record/Customers'
11 |
12 | epoch_time = int(time.time())
13 | cust_id = 'cust-' + str(epoch_time)
14 | cust_id = 'c198'
15 |
16 | post_data = {
17 | 'cust_id': cust_id,
18 | 'name': 'Standard',
19 | 'email': 'admin@bc.edu',
20 | 'phone': '555-1234',
21 | 'region': 'West',
22 | 'credit_rating': 198,
23 | 'last_updated': '2024-10-19'
24 | }
25 |
26 |
27 | def test_index():
28 | with Client(app) as client:
29 | response = client.http.post(
30 | testpath,
31 | headers={'Content-Type':'application/json'},
32 | body=json.dumps(post_data)
33 | )
34 |
35 | print(json.dumps(response.json_body, indent=2))
36 |
37 |
38 | test_index()
--------------------------------------------------------------------------------