Python の Boto3 での DynamoDB - クエリのチート シートと例


Boto3とは?



Boto3 は、AWS (Amazon Web Services) 用の Python ライブラリであり、DynamoDB を含むサービスとのやり取りを支援します.DynamoDB Python SDK と考えることができます.開発者が AWS リソースと DynamoDB テーブルとアイテムを管理および作成できるようにします.

同様のガイドを探しているが、Node.js、 you can find it hereJavaRust 、および Golang / Go here を探している場合.

DynamoDB Boto3 クエリの例のリスト


  • Connecting Boto3 to DynamoDB
  • Create Table
  • Get All Items / Scan
  • Get Item
  • Batch Get Item
  • Put Item
  • Query Set of Items
  • Update Item
  • Conditionally Update Item
  • Increment Item Attribute
  • Delete Item
  • Delete All Items
  • Query with Sorting
  • Query Pagination
  • Run DynamoDB Local

  • Boto3 を DynamoDB に接続する

    Connecting to DynamoDB with boto3 is simple if you want to do that using Access and Secret Key combination:

    import boto3
    
    client = boto3.client('dynamodb',
      aws_access_key_id='yyyy',
      aws_secret_access_key='xxxx',
      region_name='us-east-1')
    

    Keep in mind that using access and secret keys is against best security practices, and you should instead use IAM roles/policies to interact with DynamoDB. Boto3, if ran on Lamba function or EC2 instance, will automatically consume IAM Role attached to it.

    Boto3 でテーブルを作成

    DynamoDB structures data in tables, so if you want to save some data to DynamoDB, first you need to create a table. You can do that using AWS Console, AWS CLI or using boto3, like this:

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
    
    
    table = dynamodb.create_table(
        TableName='Movies',
        KeySchema=[
            {
                'AttributeName': 'year',
                'KeyType': 'HASH'  #Partition key
            },
            {
                'AttributeName': 'title',
                'KeyType': 'RANGE'  #Sort key
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'id',
                'AttributeType': 'N'
            },
            {
                'AttributeName': 'createdAt',
                'AttributeType': 'S'
            },
    
        ],
        ProvisionedThroughput={
            'ReadCapacityUnits': 10,
            'WriteCapacityUnits': 10
        }
    )
    
    print("Table status:", table.table_status)
    

    Keep in mind that provisioning a table takes some before it's active. If you want to know when it's ready to be used, you can use waiter function.

    import botocore.session
    
    session = botocore.session.get_session()
    dynamodb = session.create_client('dynamodb', region_name='us-east-1') # low-level client
    
    waiter = dynamodb.get_waiter('table_exists')
    waiter.wait(TableName="my-table-name")
    

    Boto3 Get All Items 別名

    To get all items from DynamoDB table, you can use Scan問題は、Scan が要求で返すデータ量に 1 MB の制限があるため、結果をループでページ分割する必要があることです.

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.scan()
    data = response['Items']
    
    while 'LastEvaluatedKey' in response:
        response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
        data.extend(response['Items'])
    


    次のように結果をフィルタリングするために、FilterExpression 属性を適用できます.

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.scan(FilterExpression=Attr('country').eq('US') & Attr('city').eq('NYC'))
    data = response['Items']
    
    while 'LastEvaluatedKey' in response:
        response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
        data.extend(response['Items'])
    


    Boto3 アイテムを取得

    To get a single item from DynamoDB using Partition Key (and Sort Key if using composite key )、GetItem 操作を使用できます.

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.get_item(Key={
      primaryKeyName: "ID-1",
      sortKeyName: "SORT_2"
    })
    

    primaryKeyNamesortKeyName をテーブルの実際のキーに置き換えることに注意してください.

    Boto3 バッチ取得アイテム

    If you want to retrieve multiple items identified by a key(s) in one call, use batch_get_item call with the following syntax:

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    response = dynamodb.batch_get_item(
            RequestItems={
                'my-table': {
                    'Keys': [
                        {
                            'id': 1
                        },
                        {
                            'id': 2
                        },
                    ],
                    'ConsistentRead': True
                }
            },
            ReturnConsumedCapacity='TOTAL'
        )
    

    Keep in mind that batch_get_item is limited to 100 items and 16 MB of data.

    Boto3プットアイテム

    To write a single item into the DynamoDB Table, use PutItem operation:

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.put_item(
        Item={
            'id': 1,
            'title': 'my-document-title',
            'content': 'some-content',
        }
    )
    

    一連のアイテムに対する Boto3 クエリ

    Alternative way to get a collection of items is the Query method. Query is much faster than Scan because it uses . It should be your preferred way to get a collection of items with the same partition key.

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.query(
        KeyConditionExpression=Key('id').eq(1)
    )
    
    for i in response['Items']:
        print(i['title'], ":", i['description'])
    

    Keep in mind that Query can return up to 1MB of data and you can also use FilterExpression s here to narrow the results on non-key attributes.

    If you don't know how to construct your Query, use Dynobase with feature which will automatically generate it for you.

    Boto3 更新アイテム

    DynamoDB update_item operation consists of three primary attributes:

    • Key - which object should be updated
    • ExpressionAttributeValues - map with new values
    • UpdateExpression - how these new values should be applied to the object in the table

    They can be used like this:

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.update_item(
        Key={
            'id': '894673'
        },
        UpdateExpression='SET country = :newCountry",
        ExpressionAttributeValues={
            ':newCountry': "Canada"
        },
        ReturnValues="UPDATED_NEW"
    )
    

    Boto3 条件付き更新アイテム

    Moreover, you can also add a ConditionExpression parameter, which restricts the update logic only if the evaluated expression equals true .

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.update_item(
        Key={
            'id': '894673'
        },
        UpdateExpression='SET country = :newCountry",
        ConditionExpression='attribute_not_exists(deletedAt)' # Do not update if deleted
        ExpressionAttributeValues={
            ':newCountry': "Canada"
        },
        ReturnValues="UPDATED_NEW"
    )
    

    Boto3インクリメントアイテム属性

    Incrementing a Number value in DynamoDB item can be achieved in two ways:

    1. Fetch item, update the value with code and send a Put request overwriting item
    2. Using update_item operation.

    While it might be tempting to use first method because Update syntax is unfriendly, I strongly recommend using second one because of the fact it's much faster (requires only one request) and atomic (imagine value updated by other client after you fetched item).

    To do that using single update_item operation, use following syntax:

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.update_item(
        Key={
            'id': '777'
        },
        UpdateExpression='SET score.#s = score.#s + :val",
        ExpressionAttributeNames={
            "#s": "goals"
        },
        ExpressionAttributeValues={
            ':val': decimal.Decimal(1)
        },
        ReturnValues="UPDATED_NEW"
    )
    

    Boto3 アイテムの削除

    Deleting a single item from DynamoDB table is similar to GetItem operation. Key argument accepts primary key and sort/range key if table has composite key.

    import boto3
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.table.delete_item(Key={
        primaryKeyName: primaryKeyValue
    })
    

    Boto3 すべてのアイテムを削除

    Unfortunately, there's no easy way to delete all items from DynamoDB just like in SQL-based databases by using DELETE FROM my-table; . To achieve the same result in DynamoDB, you need to query/scan to get all the items in a table using pagination until all items are scanned and then perform delete operation one-by-one on each record.

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name=region)
    table = dynamodb.Table('my-table')
    
    with table.batch_writer() as batch:
         # Iterate through table until it's fully scanned
        while scan is None or 'LastEvaluatedKey' in scan:
            if scan is not None and 'LastEvaluatedKey' in scan:
                scan = table.scan(
                    ProjectionExpression='yourPrimaryKey', # Replace with your actual Primary Key
                    ExclusiveStartKey=scan['LastEvaluatedKey'],
                )
            else:
                scan = table.scan(ProjectionExpression='yourPrimaryKey')
    
            for item in scan['Items']:
                batch.delete_item(Key={'yourPrimaryKey': item['yourPrimaryKey']})
    
    Fortunately, this is possible just with 3 clicks using Dynobase .

    AWS または DynamoDB によって から配布されます.それに接続するのは、Scan 呼び出しで LastEvaluatedKey パラメータを変更するのと同じくらい簡単です.

    import boto3
    
    dynamodb = boto3.resource('dynamodb', region_name=region)
    
    table = dynamodb.Table('my-table')
    
    response = table.query(
        ScanIndexForward=False # true = ascending, false = descending
    )
    data = response['Items']
    


    Boto3 Query with Sorting の詳細をご覧ください.