I have downloaded local version for Amazon DynamoDB. I am trying to create a table using shell. When I run the code from shell it gives me an error:
"message":"The security token included in the request is invalid."
"code":"UnrecognizedClientException"
"time":"2017-04-27T12:50:35.880Z"
"statusCode":400
"retryable":false
Create code is:
var dynamodb = new AWS.DynamoDB();
var params = {
"AttributeDefinitions": [
{
"AttributeName": "UserId",
"AttributeType": "N"
},
{
"AttributeName": "FirstName",
"AttributeType": "S"
},
{
"AttributeName": "LastName",
"AttributeType": "S"
},
{
"AttributeName": "CellPhoneNumber",
"AttributeType": "N"
}
],
"TableName": "Users",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CellPhoneNumber",
"KeyType": "RANGE"
}
],
"LocalSecondaryIndexes": [
{
"IndexName": "UserIndex",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CellPhoneNumber",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
}
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
dynamodb.createTable(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});
How do I create a table in local DynamoDB? Do I need to create a DB first? I am asking this because I have always worked on SQL and this is the first time I am using NoSQL
No need to create database. Just need to create table.
Use the below configuration for local dynamodb. The endpoint URL is important. The other attributes are dummy values (i.e. it can be any values).
var creds = new AWS.Credentials('akid', 'secret', 'session');
AWS.config.update({
region: "us-west-2",
endpoint: "http://localhost:8000",
credentials : creds
});
Also, no need to define all the attributes while creating the table. Only key attributes need to be defined. Otherwise, you will get error.
Full code to create table (should be executed on http://localhost:8000/shell/):-
var dynamodb = new AWS.DynamoDB({
region: 'us-east-1',
endpoint: "http://localhost:8000"
});
var tableName = "Movies";
var params = {
"AttributeDefinitions": [
{
"AttributeName": "UserId",
"AttributeType": "N"
},
{
"AttributeName": "CellPhoneNumber",
"AttributeType": "N"
}
],
"TableName": "PBUsers",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CellPhoneNumber",
"KeyType": "RANGE"
}
],
"LocalSecondaryIndexes": [
{
"IndexName": "UserIndex",
"KeySchema": [
{
"AttributeName": "UserId",
"KeyType": "HASH"
},
{
"AttributeName": "CellPhoneNumber",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "KEYS_ONLY"
}
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
}
}
dynamodb.createTable(params, function(err, data) {
if (err) {
if (err.code === "ResourceInUseException" && err.message === "Cannot create preexisting table") {
console.log("message ====>" + err.message);
} else {
console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
}
} else {
console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
}
});
var params = {
TableName: 'student',
KeySchema: [
{
AttributeName: 'sid',
KeyType: 'HASH',
},
],
AttributeDefinitions: [
{
AttributeName: 'sid',
AttributeType: 'N',
},
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10,
},
};
dynamodb.createTable(params, function(err, data) {
if (err) ppJson(err); // an error occurred
else ppJson(data); // successful response
});
You need to also install aws-amplify cli locally as well before you can create a local DynamoDB table.
npm install -g #aws-amplify/cli
Related
Here's my dynamoose schema for table seller
const schema = new dynamoose.Schema({
PK: {
type: String, //ni letak emel.toLowerCase() + #main/business/delivery/ehailing
hashKey: true,
},
SK: {
type: String,
rangeKey: true,
"index": { //utk 'auto' display kedai bila user ada kat location tu
"name": "SKIndex",
"global": true,
"rangeKey": "location"
}
},
"location": String,
}, {
"saveUnknown": true,
"timestamps": true
});
As you can see above, I created a GSI with the SK as the hashkey named SKIndex and having location as the rangeKey. So I tried to perform the query below
var SKIndex_search = "some value"
var locality = "some value too"
var filter = new dynamoose.Condition().where("SKIndex").eq(SKIndex_search).filter("location").beginsWith(locality);
var getResult = await Seller.query(filter).exec()
but it will always return the error "InvalidParameter: Index can't be found for query."
==============
When running this query Seller.query(SKIndex_search).using("SKIndex").filter("location").beginsWith(locality).exec()
It will display the error message ValidationException: Query condition missed key schema element
Full error log:
aws:dynamodb:describeTable:response - {
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "PK",
"AttributeType": "S"
},
{
"AttributeName": "SK",
"AttributeType": "S"
},
{
"AttributeName": "location",
"AttributeType": "S"
}
],
"TableName": "earthlings_seller",
"KeySchema": [
{
"AttributeName": "PK",
"KeyType": "HASH"
},
{
"AttributeName": "SK",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2021-06-26T20:50:13.233Z",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T00:00:00.000Z",
"LastDecreaseDateTime": "1970-01-01T00:00:00.000Z",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"TableSizeBytes": 312,
"ItemCount": 1,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/earthlings_seller",
"GlobalSecondaryIndexes": [
{
"IndexName": "SKIndex",
"KeySchema": [
{
"AttributeName": "SK",
"KeyType": "HASH"
},
{
"AttributeName": "location",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
},
"IndexSizeBytes": 312,
"ItemCount": 1,
"IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/earthlings_seller/index/SKIndex"
}
]
}
}
aws:dynamodb:query:request - {
"ExpressionAttributeNames": {
"#qra": "location"
},
"ExpressionAttributeValues": {
":qrv": {
"S": "nilai"
}
},
"TableName": "earthlings_seller",
"IndexName": "SKIndex",
"KeyConditionExpression": "begins_with (#qra, :qrv)"
}
As descrribed in the Dynamoose documentation, where takes in a key attribute. This key represents an attribute name (SK), not an index name (SKIndex).
Changing your code to the following should work.
new dynamoose.Condition().where("SK").eq(SKIndex_search).filter("location").beginsWith(locality);
You can also use the using function to manually set a specific index to run your query on. However this is optional. Dynamoose will use a system to look through your indexes and pick one that best matches your query you are making.
I need to create a dynamo db table with some attribute values using a Cloudformation template as follows:
PhoneNumber | OrderNumber
223546421 11545154
784578745 11547854
223458784 11547487
XXXXXXXXX 11578451
Were "XXXXXXXXX" is passed as a parameter.
Cloudformation template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"OrdersTable": {
"Type": "AWS::DynamoDB::Table",
"Properties": {
"TableName": "ClientOrders",
"AttributeDefinitions": [
{
"AttributeName": "PhoneNumber",
"AttributeType": "S"
},
{
"AttributeName": "OrderNumber",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "PhoneNumber",
"KeyType": "HASH"
},
{
"AttributeName": "OrderNumber",
"KeyType": "RANGE"
}
],
"TimeToLiveSpecification": {
"AttributeName": "ExpirationTime",
"Enabled": true
},
"ProvisionedThroughput": {
"ReadCapacityUnits": "10",
"WriteCapacityUnits": "5"
}
},
"DependsOn": [
"DynamoDBQueryPolicy"
]
},
"DynamoDBQueryPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "DynamoDBQueryPolicy",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "dynamodb:Query",
"Resource": "*"
}
]
},
"Roles": [
{
"Ref": "OrdersTableQueryRole"
}
]
}
},
"OrdersTableQueryRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"dynamodb.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/"
}
},
"MyPhone223546421": {
"Type": "Custom::CrtUpdDltDynamodbDocumentLambda",
"Properties": {
"ServiceToken": "arn:aws:lambda:us-east-1:accountid:function:cfn-crt-upd-dlt-dynamodb-document",
"DynamoTableName": "ClientOrders",
"DynamoKeyProperty": "PhoneNumber",
"DynamoItem": "{\n \"PhoneNumber\": \"223546421\",\n \"OrderNumber\": \"11545154\",\n \"someKey\": \"someValue\"\n}\n"
}
},
"MyPhone784578745": {
"Type": "Custom::CrtUpdDltDynamodbDocumentLambda",
"Properties": {
"ServiceToken": "arn:aws:lambda:us-east-1:accountid:function:cfn-crt-upd-dlt-dynamodb-document",
"DynamoTableName": "ClientOrders",
"DynamoKeyProperty": "PhoneNumber",
"DynamoItem": "{\n \"PhoneNumber\": \"784578745\",\n \"OrderNumber\": \"11547854\",\n \"someKey\": \"someValue\"\n}\n"
}
}
}
}
It hangs when calling the lambda, of course this needs proper edition but im lacking skills to properly set it. This is the CF template for the lambda:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
DynamoCfnLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Path: '/'
Policies:
- PolicyName: dynamodbAccessRole
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:*
Resource: '*'
- Effect: Allow
Action:
- logs:*
Resource: '*'
CfnCrtUpdDltDynamodbDocumentLambda:
Type: AWS::Lambda::Function
Properties:
FunctionName: 'cfn-crt-upd-dlt-dynamodb-document'
Code:
ZipFile: >
const AWS = require("aws-sdk");
const response = require("./cfn-response");
const docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = function(event, context) {
console.log(JSON.stringify(event, null, 2));
var item = JSON.parse(event.ResourceProperties.DynamoItem);
var keyProperty = event.ResourceProperties.DynamoKeyProperty;
var tableName = event.ResourceProperties.DynamoTableName;
if (event.RequestType == "Create" || event.RequestType == "Update") {
console.log("item:", item);
var params = {
TableName: tableName,
Item: item
};
console.log("Creating or Updating Document");
docClient.put(params, function(err, data) {
if (err) {
console.log('error creating/updating document', err);
response.send(event, context, "FAILED", {}, tableName + '_' + item[keyProperty]);
} else {
response.send(event, context, "SUCCESS", {}, tableName + '_' + item[keyProperty]);
}
});
}
if (event.RequestType == "Delete") {
console.log("Deleting a Document");
var params = {
TableName: tableName,
Key: {
[keyProperty]: item[keyProperty]
}
};
docClient.delete(params, function(err, data) {
if (err) {
response.send(event, context, "FAILED", {});
} else {
response.send(event, context, "SUCCESS", {});
}
});
}
};
Handler: index.handler
Role: !GetAtt DynamoCfnLambdaRole.Arn
Runtime: nodejs10.x
Timeout: 60
Would really appreciate some detailed explanation if someone has the time.
Thanks in advance.
So I have this JSON object
{
"id": "c66c588e",
"players": {
"M2cfydGooAMCLpQ=": {},
"ygjjgy7678": {}
}
}
For a given player Id, I want to update that particular object, so it becomes
{
"id": "c66c588e",
"players": {
"M2cfydGooAMCLpQ=": {
"cards": [
{
"cardId": "id1",
"cardTitle": "title here"
}
]
},
"ygjjgy7678": {}
}
}
This is the query I have
const params = {
TableName: process.env.DYNAMODB_GAMES_TABLE,
Key: {
id: gameId
},
UpdateExpression: 'set players.#player = list_append(if_not_exists(#cards, :empty_list), :card)',
ExpressionAttributeNames: {
'#cards': 'cards',
'#player': playerId
},
ExpressionAttributeValues: {
':card': [{
"cardId": cardId,
"cardTitle": cardTitle,
"pun": pun
}],
':empty_list': []
},
ReturnValues: "ALL_NEW"
};
But I get this error
{
"message": "The document path provided in the update expression is invalid for update",
"code": "ValidationException",
"time": "2020-05-21T00:50:32.236Z",
"requestId": "HLJJA2QQ2POAQEAJUD3143T6PJVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 38.70011614235671
}
I cannot seem to figure out how to update a particular player.
I think creating a new Index will result in additional AWS costs which I want to avoid.
I figured it out.
The key should be a valid key which you can access by obj.key and not obj[key]
Then this query will work
const params = {
TableName: process.env.DYNAMODB_GAMES_TABLE,
Key: {
id: gameId
},
UpdateExpression: 'set players.#player = list_append(if_not_exists(#cards, :empty_list), :card)',
ExpressionAttributeNames: {
'#cards': 'cards',
'#player': playerId
},
ExpressionAttributeValues: {
':card': [{
"cardId": cardId,
"cardTitle": cardTitle,
"pun": pun
}],
':empty_list': []
},
ReturnValues: "ALL_NEW"
};
I am currently creating a table in DynamoDB using the AWS cli. The command I'm using is
aws dynamodb create-table --cli-input-json file://.feature_promotions-dynamodb.json --endpoint-url http://localhost:8000
Based on the docs for create-table, I should be able to set the billing-mode to PAY_PER_REQUEST without having to set the provisioned throughput, but every time run the command I get back the following error:
An error occurred (ValidationException) when calling the CreateTable operation: No provisioned throughput specified for the table
I upgraded awscli yesterday to
aws-cli/1.16.90 Python/3.7.2 Darwin/18.2.0 botocore/1.12.80
Other than that, I'm out of ideas on how to fix it. My workaround currently is to just create the table with a provisioned throughput and then go to the console to change it, but this seems unnecessary. Ultimately I'd like to be able to run this command in a bash script without having to later fix the table settings in the AWS console.
Below is the JSON file I load in the create-table command. "BillingMode": "PAY_PER_REQUEST" attribute and value are set after "AttributeDefinition" and I would expect this to work without any error. If I remove the billing mode line, and add the following attribute to the file
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
it creates the table without any errors.
{
"TableName": "dev.feature_promotions",
"AttributeDefinitions": [
{
"AttributeName": "display_title",
"AttributeType": "S"
},
{
"AttributeName": "end_date",
"AttributeType": "N"
},
{
"AttributeName": "id",
"AttributeType": "N"
},
{
"AttributeName": "partner_id",
"AttributeType": "N"
},
{
"AttributeName": "start_date",
"AttributeType": "N"
},
{
"AttributeName": "view_scope_id",
"AttributeType": "N"
}
],
"BillingMode": "PAY_PER_REQUEST",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"GlobalSecondaryIndexes": [
{
"IndexName": "start_date-index",
"KeySchema": [
{
"AttributeName": "start_date",
"KeyType": "HASH"
},
{
"AttributeName": "id",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
},
{
"IndexName": "display_title-index",
"KeySchema": [
{
"AttributeName": "display_title",
"KeyType": "HASH"
},
{
"AttributeName": "id",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
},
{
"IndexName": "end_date-index",
"KeySchema": [
{
"AttributeName": "end_date",
"KeyType": "HASH"
},
{
"AttributeName": "id",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
},
{
"IndexName": "partner_id-index",
"KeySchema": [
{
"AttributeName": "partner_id",
"KeyType": "HASH"
},
{
"AttributeName": "id",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
},
{
"IndexName": "view_scope_id-index",
"KeySchema": [
{
"AttributeName": "view_scope_id",
"KeyType": "HASH"
},
{
"AttributeName": "id",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
}
],
"StreamSpecification": {
"StreamEnabled": true,
"StreamViewType": "NEW_AND_OLD_IMAGES"
},
"SSESpecification": {
"Enabled": true,
"SSEType": "AES256",
"KMSMasterKeyId": ""
}
}
What am I doing wrong?
You can only use one of "BillingMode": "PAY_PER_REQUEST" or ProvisionedThroughput on a table or GSI. You need to remove ProvisionedThroughput on any on-demand resources.
EDIT: To be clear, you can't use ProvisionedThroughput on the indexes of a table that is on-demand. To fix this, just remove all instances of ProvisionedThroughput. Your indexes will then also be on-demand.
Here's (the DynamoDB part of) my Troposphere-generated JSON:
"sandbox": {
"Properties": {
"AttributeDefinitions": [
{
"AttributeName": "audit_id",
"AttributeType": "S"
},
{
"AttributeName": "status",
"AttributeType": "S"
},
{
"AttributeName": "filename",
"AttributeType": "S"
},
{
"AttributeName": "file_detected_dt",
"AttributeType": "S"
},
{
"AttributeName": "time_taken",
"AttributeType": "N"
},
{
"AttributeName": "number_rows_processed_file",
"AttributeType": "N"
},
{
"AttributeName": "number_rows_created_db",
"AttributeType": "N"
},
{
"AttributeName": "info_messages",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "audit_id",
"KeyType": "HASH"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": {
"Ref": "ReadCapacityUnits"
},
"WriteCapacityUnits": {
"Ref": "WriteCapacityUnits"
}
}
},
"Type": "AWS::DynamoDB::Table"
}
CloudFormation gives me this error on trying to spin up the VPC: Property AttributeDefinitions is inconsistent with the KeySchema of the table and the secondary indexes.
But ... is it? I'm specifying audit_id as a lone key, and it definitely exists within the AttributeDefinitions list. I'm very new to CF (and Dynamo, for that matter) so I may well be missing something extremely obvious, but it's not apparent to me at the moment.
I've googled around and only really found one mention of this error, and it was more to do with a layer between developer and CF, rather than CF itself.
Can anyone point out what's wrong with my template?
This was down to a misunderstanding on my part regarding DynamoDB. The only attributes that should be defined here are those that will be used as keys. Thus, changing the AttributeDefinitions array to the following solved the problem:
"AttributeDefinitions": [
{
"AttributeName": "audit_id",
"AttributeType": "S"
}
]