¿Cómo crear la tabla dynamodb usando serverless.yml y eliminar sus elementos usando python boto3?

Sep 25 2020

Creé la tabla dynamodb usando serverless.yml como se muestra a continuación:

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

Pero tengo este problema:

Ocurrió un error: myTable - Uno o más valores de parámetro no eran válidos: el número de atributos en KeySchema no coincide exactamente con el número de atributos definidos en AttributeDefinitions (Servicio: AmazonDynamoDBv2; Código de estado: 400; Código de error: ValidationException; ID de solicitud: PEI9OT7E72HQN4N5MQUOIUQUAQ18JGV4KVQNS; : nulo).

¿Podrías ayudarme a crear la tabla dynamodb usando serverless.yml? ¿Y cómo puedo eliminar los elementos cuyo nombre es "Primero" en esta tabla usando python boto3?

Respuestas

2 Marcin Oct 14 2020 at 06:06

Si desea mantener su KeySchema, debe dejar lastname de 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

Pero si desea conservar lastname, puede definir un índice secundario local para su tabla:

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

Con lo anterior, puede ordenar para lastnameusar el LSI, mientras firstnameque se usaría en la tabla principal.

¿Cómo puedo eliminar los elementos cuyo nombre es "Primero" en esta tabla usando python boto3?

No puede hacerlo directamente con o sin boto3, a menos que desee realizar un escaneo , lo cual debe evitarse ya que puede ser costoso y no es eficiente. La solución general es definir índices secundarios globales donde firstnamesería la nueva clave principal. Luego, consultará al GSI por el firstnamede interés para obtener el iddel registro que desea eliminar. Si tiene varios registros con el mismo firstname, que probablemente será el caso, obtendrá una cantidad de registros (las claves primarias GSI no necesitan ser únicas , a diferencia de la tabla primaria).

Tabla de ejemplo con LSI y GSI:

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
PubuduJayawardana Sep 25 2020 at 18:55

La razón es que todos sus AttributeNames en AttributeDefinitionsdeben incluirse también en el KeySchema. Puedo ver que lastnamefalta el atributo allí.