如何在CloudFormation中使用基础结构代码实现DynamoDB全局二级索引

时间:2019-06-14 16:46:05

标签: amazon-dynamodb yaml amazon-cloudformation infrastructure-as-a-code

我正在使用基础架构即代码在CloudFormation中实施GSI。我要做的就是使用此表将主DynamoTable中的条目计数。主要故事如下:

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE

我不需要原始表中的密钥,我只需要为新GSI创建一个新的HASH密钥即可告诉我我要跟踪的计数来自哪个表,即上面的表。 / p>

以下是到目前为止我尝试实施GSI的方式:

# Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
          - IndexName: gsiCaseCountTable
            KeySchema: 
              - AttributeName: table-name
                KeyType: HASH
            ProvisionedThroughput:
              ReadCapacityUnits: 5
              WriteCapacityUnits: 5

但是,我得到的错误如下:

An error occurred: CaseRecords - Property Projection cannot be empty..

当我包含投影时,仅是原始表中的userId,只是为了跟踪每个用户在原始表中的条目计数,我尝试以下操作:

 Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: table-name
          KeyType: HASH
        Projection:
          NonKeyAttributes:
          - userId
          ProjectionType: INCLUDE
        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5

但是这也会返回一个错误:

An error occurred: CaseRecords - Property AttributeDefinitions is inconsistent with the KeySchema of the table and the secondary indexes.

如何使用CloudFormation模板在Dynamo中正确实现全局二级索引,以便可以在原始表中记录条目数??

谢谢。

更新

万一有人想知道这是我如何部署它的话。这不是一个完美的解决方案,但它可以让我跟踪并计数项目表中的条目:

# NOTE: DynamoDB Serverless Configuration
# NoSQL Table for CaseRecord DB

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
        # ReadCapacityUnits: ${self:custom.tableThroughput}
        # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: userId
          KeyType: HASH
        Projection:
          ProjectionType: KEYS_ONLY

更新#2-失败

基于下面@Pedro Arantes提供的信息,我正在尝试使用要使用的属性定义来实现GSI。但是,这也失败了。以下是实现,这是我使用的AWS Doc的链接:AWS GSI Doc,这是失败的实现:

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
        - AttributeName: table-name
          AttributeType: S
        - AttributeName: count
          AttributeType: N
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
        # ReadCapacityUnits: ${self:custom.tableThroughput}
        # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
      - IndexName: gsiCaseCountTable
        KeySchema:
        - AttributeName: table-name
          KeyType: HASH
        Projection: 
          NonKeyAttributes: 
            - userId
            - count
          ProjectionType: INCLUDE

如何才能使其仅与在NonKeyAttributes中声明的AttributeDefinitions一起使用?

1 个答案:

答案 0 :(得分:2)

您需要在table-name属性中添加AttributeDefinitions。来自docs

  

AttributeDefinitions

     

描述表和表的关键架构的属性列表   索引。允许重复。

因此,即使您没有在原始表中使用某些属性,也必须声明能够在您的GSI中使用。

更新#2-失败

您正在使用在userId上定义为count的键属性AttributeDefinitionsNonKeyAttributes(但它们键属性) Projection。您无需添加它们,因为它们是自动投影的。来自docs

  

AWS :: DynamoDB :: Table Projection

     

表示从表复制(投影)到索引中的属性。这些是自动投影的主键属性和索引键属性的补充。

最终模板

Resources:
  CaseRecords:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.tableName}
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
        - AttributeName: caseRecordId
          AttributeType: S
        - AttributeName: table-name
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
        - AttributeName: caseRecordId
          KeyType: RANGE
      # Set the capacity based on the stage
      # ProvisionedThroughput:
      # ReadCapacityUnits: ${self:custom.tableThroughput}
      # WriteCapacityUnits: ${self:custom.tableThroughput}
      # Implement a GSI to handle item count totals
      GlobalSecondaryIndexes:
        - IndexName: gsiCaseCountTable
          KeySchema:
            - AttributeName: table-name
              KeyType: HASH
          Projection:
            NonKeyAttributes:
              - count
            ProjectionType: INCLUDE

注意事项:

  1. count不应位于AttributeDefinitions上,因为您没有将其用作键。

  2. 您不需要在userId上添加Projection,因为它是在AttributeDefinitions中定义的,因此会自动进行投影。