首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用DynamoDB将GSI添加到CloudFormation表

无法使用DynamoDB将GSI添加到CloudFormation表
EN

Stack Overflow用户
提问于 2016-04-28 14:57:48
回答 5查看 16.2K关注 0票数 16

我有一个现有的DynamoDB表,它被定义为CloudFormation堆栈的一部分。根据CFN AWS::DynamoDB::表文档,GlobalSecondaryIndexes属性不需要替换。它甚至详细说明了以下几点。

您可以不间断地删除或添加一个全局辅助索引。

以及下面的..。

如果更新一个表以包含新的全局辅助索引,AWS CloudFormation将启动索引创建,然后继续进行堆栈更新。AWS CloudFormation不会等待索引完成创建,因为回填阶段可能需要很长时间,这取决于表的大小。

但是,在实践中,当我试图执行更新时,会收到以下错误消息:

代码语言:javascript
复制
CloudFormation cannot update a stack when a custom-named resource requires replacing. Rename mytablename and update the stack again.

由于我要添加一个使用新属性的GSI,所以我不得不修改AttributeDefinitions,这表明它确实需要替换。然而,即使我试图添加一个只定义在AttributeDefinitions中的现有属性的GSI,我仍然会得到相同的错误消息。

下面是我的表的原始CFN定义中的片段:

代码语言:javascript
复制
{
  "myTable": {
    "Type": "AWS::DynamoDB::Table",
    "Properties": {
      "TableName": "mytablename",
      "AttributeDefinitions": [
        {
          "AttributeName": "entryId",
          "AttributeType": "S"
        },
        {
          "AttributeName": "entryName",
          "AttributeType": "S"
        },
        {
          "AttributeName": "appId",
          "AttributeType": "S"
        }
      ],
      "KeySchema": [
        {
          "KeyType": "HASH",
          "AttributeName": "entryId"
        },
        {
          "KeyType": "RANGE",
          "AttributeName": "entryName"
        }
      ],
      "ProvisionedThroughput": {
        "ReadCapacityUnits": {
          "Ref": "readThroughput"
        },
        "WriteCapacityUnits": {
          "Ref": "writeThroughput"
        }
      },
      "GlobalSecondaryIndexes": [
        {
            "IndexName": "appId-index",
          "KeySchema": [
            {
              "KeyType": "HASH",
              "AttributeName": "appId"
            }
          ],
          "Projection": {
            "ProjectionType": "KEYS_ONLY"
          },
          "ProvisionedThroughput": {
            "ReadCapacityUnits": {
              "Ref": "readThroughput"
            },
            "WriteCapacityUnits": {
              "Ref": "writeThroughput"
            }
          }
        }
      ]
    }
  }
}

下面是我想更新的内容:

代码语言:javascript
复制
{
  "myTable": {
    "Type": "AWS::DynamoDB::Table",
    "Properties": {
      "TableName": "mytablename",
      "AttributeDefinitions": [
        {
          "AttributeName": "entryId",
          "AttributeType": "S"
        },
        {
          "AttributeName": "entryName",
          "AttributeType": "S"
        },
        {
          "AttributeName": "appId",
          "AttributeType": "S"
        },
        {
          "AttributeName": "userId",
          "AttributeType": "S"
        }
      ],
      "KeySchema": [
        {
          "KeyType": "HASH",
          "AttributeName": "entryId"
        },
        {
          "KeyType": "RANGE",
          "AttributeName": "entryName"
        }
      ],
      "ProvisionedThroughput": {
        "ReadCapacityUnits": {
          "Ref": "readThroughput"
        },
        "WriteCapacityUnits": {
          "Ref": "writeThroughput"
        }
      },
      "GlobalSecondaryIndexes": [
        {
            "IndexName": "appId-index",
          "KeySchema": [
            {
              "KeyType": "HASH",
              "AttributeName": "appId"
            }
          ],
          "Projection": {
            "ProjectionType": "KEYS_ONLY"
          },
          "ProvisionedThroughput": {
            "ReadCapacityUnits": {
              "Ref": "readThroughput"
            },
            "WriteCapacityUnits": {
              "Ref": "writeThroughput"
            }
          }
        },
        {
          "IndexName": "userId-index",
          "KeySchema": [
            {
              "KeyType": "HASH",
              "AttributeName": "userId"
            }
          ],
          "Projection": {
            "ProjectionType": "KEYS_ONLY"
          },
          "ProvisionedThroughput": {
            "ReadCapacityUnits": {
              "Ref": "readThroughput"
            },
            "WriteCapacityUnits": {
              "Ref": "writeThroughput"
            }
          }
        }
      ]
    }
  }
}

但是,正如我前面提到的,即使我没有在userId中定义AttributeDefinitions并在新的GSI定义中使用一个现有属性,它也不能工作,并且在相同的错误消息中失败。

EN

回答 5

Stack Overflow用户

发布于 2016-04-30 02:07:46

我今天也犯了同样的错误,并得到了亚马逊技术支持部门的答复。问题是您提供了一个TableName字段。CloudFormation想要负责为您命名您的表。显然,当您为它们提供您自己的名称时,这是您在更新中得到的替换表的错误(不确定它为什么需要替换,但这是医生说的)

对我来说,这使得CloudFormation在维护我的DynamoDB表时毫无用处。我必须在配置中构建,这样我的代码才能动态地知道CloudFormation为我生成的随机表名是什么。

票数 10
EN

Stack Overflow用户

发布于 2016-05-17 15:40:40

AWS支助部门对我的答复:

解决办法A

  1. 将数据从表导出到s3
  2. 用新的表名(tablename2)更新堆栈,添加了
    • 请注意,这将丢失所有当前条目,因此肯定会首先备份到s3!

  1. 再次更新堆栈,回到在dynamodb表中使用tablename1
  2. 从s3导入数据可以通过使用数据管道来简化,请参阅
    • http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBPipeline.html

优点是,应用程序代码可以继续使用固定名称。但是,两次更新堆栈和导出/导入数据需要一些工作才能在自定义脚本中实现自动化。

变通办法B

  1. 备份数据
  2. 让CloudFormation给表命名
  3. 使用AWS检索表名,方法是通过逻辑id描述堆栈资源来获取表名,并从输出中获取那里的表名。

虽然我认为这避免了额外的堆栈更新(仍然认为需要导出/导入数据),但缺点是在代码中使用网络调用来获取表名。见* http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CloudFormation.html#describeStackResource-property

同样,这是一个已知的问题--支持正在推动服务团队前进,因为我们知道这是一个非常常见的用例和痛点。在测试产品之前,请先在测试环境上尝试一种解决方法。

票数 7
EN

Stack Overflow用户

发布于 2020-01-03 07:48:17

这个问题是怎么发生的?对于我来说,在dynamoDB控制台中手动删除GSI,然后通过cloudformation添加GSI,更新堆栈得到了这个错误。

解决方案:删除cloudformation中的GSI,执行更新堆栈,然后添加回GSI,再次执行更新堆栈,工作正常。

猜测cloudformation有自己的缓存,无法告诉您在控制台中手动进行的更改。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36918408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档