Как создать таблицу dynamodb с помощью serverless.yml и удалить ее элементы с помощью python boto3?

#python #aws-lambda #amazon-dynamodb #boto3 #serverless

#python #aws-lambda #amazon-dynamodb #boto3 #бессерверный

Вопрос:

Я создал таблицу dynamodb с помощью serverless.yml, как показано ниже:

 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
  

Но у меня есть эта проблема:

Произошла ошибка: myTable — одно или несколько значений параметра неверны: количество атрибутов в KeySchema не соответствует количеству атрибутов, определенных в AttributeDefinitions (Сервис: AmazonDynamoDBv2; Код состояния: 400; Код ошибки: Исключение ValidationException; Идентификатор запроса: PEI9OT7E72HQN4N5MQUOIUQ18JVV4KQNSO5AEMVJF66Q9ASUAAJG; Прокси: null).

Не могли бы вы помочь мне создать таблицу dynamodb с помощью serverless.yml? И как я могу удалить элементы, имя которых является «Первым» в этой таблице, используя python boto3?

Ответ №1:

Если вы хотите сохранить свой KeySchema , вам нужно отказаться lastname от 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 , вы можете определить локальный вторичный индекс для своей таблицы:

 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
  

С помощью вышесказанного вы можете выполнить сортировку для lastname использования LSI, в то время firstname как она будет использоваться в основной таблице.

как я могу удалить элементы, имя которых является «Первым» в этой таблице, используя python boto3?

Вы не можете сделать это напрямую с помощью boto3 или без него, если только вы не хотите выполнять сканирование, чего следует избегать, поскольку это может быть дорогостоящим и неэффективным. Общее решение — определить глобальные вторичные индексы, где firstname будет новый первичный ключ. Затем вы должны запросить GSI для firstname интересующей id вас записи, которую вы хотите удалить. Если у вас есть несколько записей с одинаковыми firstname значениями, что, вероятно, так и будет, вы получите обратно несколько записей (первичные ключи GSI не обязательно должны быть уникальными, в отличие от первичной таблицы).

Пример таблицы с LSI и 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
  

Ответ №2:

Причина в том, что все ваши AttributeDefinitions имена атрибутов также должны быть включены в KeySchema . Я вижу lastname , что атрибут там отсутствует.

Комментарии:

1. Не могли бы вы приложить образец?

Ответ №3:

Вам просто нужно удалить атрибут ‘lastname’ из AttributeDefinitions. Все, что определено как AttributeDefinitions, должно использоваться в разделе KeySchema . Не забудьте экспортировать свое имя таблицы, Arn и StreamArn, чтобы вы могли ссылаться на них в других службах и политиках IAM.

https://carova.io/snippets/serverless-aws-cloudformation-output-stack-variables

Еще один бонус при экспорте переменных, таких как TableName или StreamArn, в ваш стек CloudFormation — вы можете ссылаться на них в разных стеках CloudFormation.

https://carova.io/snippets/serverless-aws-reference-other-cloudformation-stack-variables