export const meta = {
  title: `Calling DynamoDB from a Lambda function in Python`,
  description: `How to interact with a DynamoDB database from a Lambda function in Python`,
};

The easiest way to interact with DynamoDB from Lambda in a Python environment is to use the [boto3 DynamoDB client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html). In this guide you will learn how to interact with a DynamoDB database from a Lambda function using the Python runtime.

You will learn how to perform [put_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.put_item), [get_item](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.get_item), [scan](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.scan), and [query](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.query) operations.

Note that the Amplify-generated Python Lambda functions use [Pipenv](https://pypi.org/project/pipenv/) for packaging. To install a dependency, such as `boto3`, first change into your function's Amplify folder, then enter the Pipenv virtual environment and install inside it.

```sh
$ cd amplify/backend/function/your-function-name
$ pipenv shell
$ pipenv install boto3
```
### Creating an item in DynamoDB from Lambda

To create an item in DynamoDB you can use the `put` method:

```python
import boto3

client = boto3.client('dynamodb')

def handler(event, context):
  data = client.put_item(
    TableName='your-table-name',
    Item={
        'id': {
          'S': '005'
        },
        'price': {
          'N': '500'
        },
        'name': {
          'S': 'Yeezys'
        }
    }
  )

  response = {
      'statusCode': 200,
      'body': 'successfully created item!',
      'headers': {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
      },
  }
  
  return response
```

### Getting an item by primary key in DynamoDB from Lambda

To get an item by primary key in DynamoDB you can use the `get` method. A `get` request returns a single item given the primary key of that item:

```python
import json
import boto3

client = boto3.client('dynamodb')

def handler(event, context):
  data = client.get_item(
    TableName='your-table-name',
    Key={
        'id': {
          'S': '005'
        }
    }
  )

  response = {
      'statusCode': 200,
      'body': json.dumps(data),
      'headers': {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
      },
  }
  
  return response
```

### Scanning a table

A `scan` returns one or more items and item attributes by accessing every item in a table or a secondary index (limit of 1 MB of data).

```python
import json
import boto3

client = boto3.client('dynamodb')

def handler(event, context):
  data = client.scan(
    TableName='your-table-name'
  )

  response = {
      'statusCode': 200,
      'body': json.dumps(data),
      'headers': {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
      },
  }
  
  return response
```

### Querying a table

A `query` returns one or more items and item attributes by querying items from a table by primary key or secondary index.

```python
import json
import boto3

client = boto3.client('dynamodb')

def handler(event, context):
  data = client.query(
    TableName='your-table-name',
    IndexName='some-index',
    KeyConditionExpression='#name = :value',
    ExpressionAttributeValues={
      ':value': {
        'S': 'shoes'
      }
    },
    ExpressionAttributeNames={
      '#name': 'name'
    }
  )

  response = {
      'statusCode': 200,
      'body': json.dumps(data),
      'headers': {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
      },
  }
  
  return response
```
