Closed shomeprasanjit closed 4 years ago
a workaround is to set a capacity and if needed select onDemand from console once it created. function clearTableSchema(table) { .... provisionedThroughput(table); return table }
WHERE :
function provisionedThroughput(table){
console.log('provisionedThroughput');
const defaultValue=5;
if (table.ProvisionedThroughput.ReadCapacityUnits === 0) {
table.ProvisionedThroughput.ReadCapacityUnits = defaultValue;
}
if (table.ProvisionedThroughput.WriteCapacityUnits === 0) {
table.ProvisionedThroughput.WriteCapacityUnits = defaultValue;
}
for(var index= 0; index < table.GlobalSecondaryIndexes.length; index++)
{
if (table.GlobalSecondaryIndexes[index].ProvisionedThroughput.ReadCapacityUnits === 0) {
table.GlobalSecondaryIndexes[index].ProvisionedThroughput.ReadCapacityUnits = defaultValue;
}
if (table.GlobalSecondaryIndexes[index].ProvisionedThroughput.WriteCapacityUnits === 0) {
table.GlobalSecondaryIndexes[index].ProvisionedThroughput.WriteCapacityUnits = defaultValue;
}
}
}
was still getting an error message as shown below.
/Users/prasanjit_shome/node_modules/aws-sdk/lib/request.js:31 throw err; ^
TypeError: Cannot read property 'length' of undefined
at clearTableSchema (/Users/prasanjit_shome/prog/common_cloud/copy-dynamodb-table/index.js:157:58)
at Response.
BUT got it working by adding if statement in "provisionedThroughput" function.
if(table.GlobalSecondaryIndexes && table.GlobalSecondaryIndexes.length > 0){ for(var index= 0; index < table.GlobalSecondaryIndexes.length; index++) { if (table.GlobalSecondaryIndexes[index].ProvisionedThroughput.ReadCapacityUnits === 0) { table.GlobalSecondaryIndexes[index].ProvisionedThroughput.ReadCapacityUnits = defaultValue; } if (table.GlobalSecondaryIndexes[index].ProvisionedThroughput.WriteCapacityUnits === 0) { table.GlobalSecondaryIndexes[index].ProvisionedThroughput.WriteCapacityUnits = defaultValue; } } }
Note about OnDemand tables - while copying, it creates provisioned destination table, we need to change it back to OnDemand from console once the table is created.
najimou: should we add it to master?
shomeprasanjit good catch. Concerning add it to master, I think it is only a workaround. const defaultValue=5; is arbitrary value, depending the numbers of items on the table. If the value provisioned is not high enough there is a risk of having errors to reach the maximum threshold... feel free to propose a PR :)
Adding both of your changes worked for me. It would probably be better to add the default value as a config option under source and destination.
As Source table has 'on-demand' capacity, it will be better to keep the same for the destination table.
As per aws documentation,
In order to do that, index.js -> clearTableSchema function code can be changed as below,
if (table.BillingModeSummary) {
table.BillingMode = table.BillingModeSummary.BillingMode;
if(table.BillingMode === "PAY_PER_REQUEST")
{
delete table.ProvisionedThroughput
}
delete table.BillingModeSummary
}
if(table.LocalSecondaryIndexes && table.LocalSecondaryIndexes.length > 0){
for(var i = 0 ; i < table.LocalSecondaryIndexes.length ; i++){
delete table.LocalSecondaryIndexes[i].IndexStatus
if(table.BillingMode === "PAY_PER_REQUEST")
{
delete table.LocalSecondaryIndexes[i].ProvisionedThroughput
}else{
delete table.LocalSecondaryIndexes[i].ProvisionedThroughput.LastIncreaseDateTime
delete table.LocalSecondaryIndexes[i].ProvisionedThroughput.LastDecreaseDateTime
delete table.LocalSecondaryIndexes[i].ProvisionedThroughput.NumberOfDecreasesToday
}
delete table.LocalSecondaryIndexes[i].IndexSizeBytes
delete table.LocalSecondaryIndexes[i].ItemCount
delete table.LocalSecondaryIndexes[i].IndexArn
delete table.LocalSecondaryIndexes[i].LatestStreamLabel
delete table.LocalSecondaryIndexes[i].LatestStreamArn
}
}
if(table.GlobalSecondaryIndexes && table.GlobalSecondaryIndexes.length > 0){
for(var j = 0 ; j < table.GlobalSecondaryIndexes.length ; j++){
delete table.GlobalSecondaryIndexes[j].IndexStatus
if(table.BillingMode === "PAY_PER_REQUEST")
{
delete table.GlobalSecondaryIndexes[j].ProvisionedThroughput
}else{
delete table.GlobalSecondaryIndexes[j].ProvisionedThroughput.LastIncreaseDateTime
delete table.GlobalSecondaryIndexes[j].ProvisionedThroughput.LastDecreaseDateTime
delete table.GlobalSecondaryIndexes[j].ProvisionedThroughput.NumberOfDecreasesToday
}
So in short, instead of keeping default 'BillingMode', we can copy mode from the source table...
Is there a chance to get this change in a new release?
Added to latest release
Hey Guys, I am getting errors while trying to copy Ondemand tables but works fine with provisioned tables.
{ ValidationException: 2 validation errors detected: Value '0' at 'provisionedThroughput.writeCapacityUnits' failed to satisfy constraint: Member must have value greater than or equal to 1; Value '0' at 'provisionedThroughput.readCapacityUnits' failed to satisfy constraint: Member must have value greater than or equal to 1 at Request.extractError (/Users/prasanjit_shome/node_modules/aws-sdk/lib/protocol/json.js:51:27) at Request.callListeners (/Users/prasanjit_shome/node_modules/aws-sdk/lib/sequential_executor.js:106:20) at Request.emit (/Users/prasanjit_shome/node_modules/aws-sdk/lib/sequential_executor.js:78:10) at Request.emit (/Users/prasanjit_shome/node_modules/aws-sdk/lib/request.js:683:14) at Request.transition (/Users/prasanjit_shome/node_modules/aws-sdk/lib/request.js:22:10) at AcceptorStateMachine.runTo (/Users/prasanjit_shome/node_modules/aws-sdk/lib/state_machine.js:14:12) at /Users/prasanjit_shome/node_modules/aws-sdk/lib/state_machine.js:26:10 at Request. (/Users/prasanjit_shome/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/Users/prasanjit_shome/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/Users/prasanjit_shome/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
message: '2 validation errors detected: Value \'0\' at \'provisionedThroughput.writeCapacityUnits\' failed to satisfy constraint: Member must have value greater than or equal to 1; Value \'0\' at \'provisionedThroughput.readCapacityUnits\' failed to satisfy constraint: Member must have value greater than or equal to 1',
code: 'ValidationException',
time: 2019-04-25T19:54:24.873Z,
requestId: 'L9MVKUQ57HSNAU189FOUGCIJDBVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 32.77870743752317 }
{ Table:
{ AttributeDefinitions: [ [Object], [Object] ],
TableName: 'XXXXXXXXXXXXXXXXX,
KeySchema: [ [Object], [Object] ],
ProvisionedThroughput: { ReadCapacityUnits: 0, WriteCapacityUnits: 0 },
StreamSpecification: { StreamEnabled: true, StreamViewType: 'NEW_IMAGE' },
SSESpecification: { Enabled: true } } }