如何使用 serverless.yml 创建 dynamodb table 并使用 python boto3 删除其中的项目?

How to create the dynamodb table using serverless.yml and delete the items of it using python boto3?

我使用 serverless.yml 创建了 dynamodb table,如下所示:

resources:
  Resources:
    myTable:
      Type: AWS::DynamoDB::Table
      DeletionPolicy: Retain
      Properties:
        TableName: myTable
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
          - AttributeName: firstname
            AttributeType: S
          - AttributeName: lastname
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
          - AttributeName: firstname
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST
        SSESpecification:
          SSEEnabled: true

但是我遇到了这个问题:

An error occurred: myTable - One or more parameter values were invalid: Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: PEI9OT7E72HQN4N5MQUOIUQ18JVV4KQNSO5AEMVJF66Q9ASUAAJG; Proxy: null).

你能帮我用 serverless.yml 创建 dynamodb table 吗? 以及如何使用 python boto3 删除此 table 中名字为“First”的项目?

原因是 AttributeDefinitions 中的所有 AttributeNames 也必须包含在 KeySchema 中。我可以看到那里缺少 lastname 属性。

如果你想保留你的 KeySchema 你必须 drop lastname from AttributeDefinitions:

Resources:
  myTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: myTable
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: firstname
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
        - AttributeName: firstname
          KeyType: RANGE
      BillingMode: PAY_PER_REQUEST
      SSESpecification:
        SSEEnabled: true

但是如果你想保留 lastname,你可以 define local secondary index 为你的 table:

Resources:
  myTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: myTable
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: firstname
          AttributeType: S
        - AttributeName: lastname
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
        - AttributeName: firstname
          KeyType: RANGE
      LocalSecondaryIndexes:
        - IndexName: by-lastname
          KeySchema: 
          - AttributeName: id
            KeyType: HASH
          - AttributeName: lastname
            KeyType: RANGE
          Projection: 
            ProjectionType: ALL
      BillingMode: PAY_PER_REQUEST
      SSESpecification:
        SSEEnabled: true

根据以上内容,您可以使用 LSI 对 lastname 进行排序,而 firstname 将用于主要 table。

how can I delete the items that first name is "First" in this table using python boto3?

无论有没有 boto3,你都不能直接,除非你想执行 scan, which should be avoided as it can be expensive and is not efficient. To general solution is to define a Global Secondary Indexes,其中 firstname 将是新的主键.然后,您将向 GSI 查询感兴趣的 firstname,以获得要删除的记录的 id。如果您有几条记录具有相同的 firstname,这可能就是这种情况,您会得到许多记录(GSI 主键 不需要是唯一的 ,不像对于主要 table).

使用 LSI 和 GSI 的示例 table:

Resources:
  myTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: myTable
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: firstname
          AttributeType: S
        - AttributeName: lastname
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
        - AttributeName: firstname
          KeyType: RANGE
      LocalSecondaryIndexes:
        - IndexName: by-lastname
          KeySchema: 
          - AttributeName: id
            KeyType: HASH
          - AttributeName: lastname
            KeyType: RANGE
          Projection: 
            ProjectionType: ALL
      GlobalSecondaryIndexes:
        - IndexName: firstname-gsi
          KeySchema: 
            - AttributeName: firstname
              KeyType: HASH
          Projection: 
            ProjectionType: ALL
          #ProvisionedThroughput: 
          #  ProvisionedThroughput        
      BillingMode: PAY_PER_REQUEST
      SSESpecification:
        SSEEnabled: true