DevGang
Авторизоваться

Использование DynamoDB с Python

DynamoDB - это быстрая производительная база данных для создания высокодоступных веб-приложений. В этой статье исследуется как взаимодействовать с DynamoDB на Python с использованием библиотеки Boto3 и подробно рассматриваются такие концепции, как параллелизм, модель лидера, регулирование и многое другое.

Базы данных NoSQL - нетабличные базы данных, которые хранят и извлекают данные иначе, чем базы данных SQL. В то время как SQL основан на таблицах, базы данных NoSQL представляют собой пары ключ-значение. Базы данных NoSQL предназначены для больших распределенных систем благодаря их быстрым и высоко масштабируемым системам.  DynamoDB - это пример базы данных NoSQL. DynamoDB быстр, способен обрабатывать множество запросов и обладает высокой масштабируемостью. Dynamo - это база данных NoSQL, предоставляемая Amazon Web Service (AWS). Python является одним из наиболее широко используемых языков программирования и имеет хорошую поддержку DynamoDB с использованием AWS SDK для Python.

В этом руководстве мы будем использовать библиотеку Boto3 для создания таблиц и запросов к ним, загрузки данных и выполнения операций CRUD DynamoDB в Python.

Исходный код этой статьи можно найти на GitHub.

Предпоссылки:

  1. Учетная запись AWS
  2. Базовые знания о DynamoDB
  3. Python
  4. Операционная система: Windows, macOS или Linux

Начало работы с DynamoDB с использованием Python

DynamoDB - это сервис AWS, который позволяет создавать таблицы базы данных для хранения и извлечения данных и обрабатывает трафик запросов. AWS предлагает набор SDK для взаимодействия с DynamoDB. Эти SDK доступны для различных языков программирования; AWS SDK для Python известен как Boto3.

Мы будем использовать Boto3 для взаимодействия Dynamodb. AWS Boto3 позволяет вам создавать, настраивать различные сервисы AWS и управлять ими. 

Локальная настройка DynamoDB

Чтобы запустить DynamoDB локально, требуется выполнить несколько шагов. Первый шаг - загрузить zip-файл DynamoDB. Этот файл следует загрузить в зависимости от вашего региона. Нажмите здесь, чтобы загрузить zip-файл.

Как только файл будет загружен, извлеките все содержимое файла и переместите его в предпочитаемый каталог на вашем устройстве.

Далее откройте командную строку, перейдите в каталог, где находится  DynamoDBLocal.jar, и запустите этот сценарий настройки:

java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb 

Если у вас возникнут какие-либо проблемы с этим процессом, скорее всего, это связанно с тем, что у вас не установлена Java на вашем локальном компьютере. Запустите эту команду для подтверждения:

java --version

После подтверждения, если у вас нет Java на вашем устройстве, вы можете загрузить его по этой ссылке.

Вторым этапом этой настройки является доступ к DynamoDB через AWS CLI или конфигурацию вашей командной строки. Для этого шага требуются ваши учетные данные AWS. Убедитесь, что у вас есть ваши учетные данные, доступные в отдельной среде. Запустите эту команду на вашем терминале, чтобы начать:

aws configure 

Скорее всего, ваши учетные данные AWS уже настроены на вашем компьютере. Если это так нажмите enter. Однако, если вы этого не сделаете, предоставьте эти сведения: 

AWS Access Key ID: "yourAccessKeyId"
AWS Secret Access Key: "yourAccessKey"
Default region name : "yourRegionName"

У нас получилось;

Подключение к DynamoDB с помощью Python (Boto3)

Сначала установите Boto3, выполнив следующую команду на вашем терминале. 

pip install boto3

Затем в вашем редакторе кода создайте dynamo-python.py файл и импортируйте библиотеку Boto3 в ерхней части файла.

import boto3

Наконец, мы создадим ресурс Boto3 DynamoDB. Это позволит подключиться к локальному экземпляру нашего сервера DynamoDB, сделайте это добавив следующую строку кода: 

dynamodb = boto3.resource('dynamodb', endpoint_url="http://localhost:8000")

Создание таблицы в DynamoDB

Мы будем создавать таблицу Dynamo с помощью функции create_table. Здесь мы называем таблицу "Books".

Эта таблица будет содержать атрибуты для ключа раздела и ключа сортировки. Нашим ключом сортировки книги будет “title”, а нашим ключом раздела будет “book_id”.

Ключ сортировки - это поле в базе данных, которое указывает порядок, в котором хранятся данные (в отсортированном порядке по значению ключа сортировки). В DynamoDB ключ сортировки для каждого поля уникален.

Ключ раздела - это атрибут, который идентифицирует элемент в базе данных. Данные с одним и тем же ключом раздела хранятся вместе, чтобы вы могли запрашивать данные. Данные ключа раздела сортируются с помощью ключа сортировки; 

Теперь добавьте приведенный ниже фрагмент кода для создания таблицы: 

import boto3

def create_books_table(dynamodb=None):
    dynamodb = boto3.resource(
        'dynamodb')
    table = dynamodb.create_table(
        TableName='Books',
        KeySchema=[
            {
                'AttributeName': 'book_id',
                'KeyType': 'HASH'  # Partition key
            },
            {
                'AttributeName': 'title',
                'KeyType': 'RANGE'  # Sort key
            }
        ],
        AttributeDefinitions=[
            {
                'AttributeName': 'book_id',
                # AttributeType refers to the data type 'N' for number type and 'S' stands for string type.
                'AttributeType': 'N'
            },
            {
                'AttributeName': 'title',
                'AttributeType': 'S'
            },
        ],
        ProvisionedThroughput={
            # ReadCapacityUnits set to 10 strongly consistent reads per second
            'ReadCapacityUnits': 10,
            'WriteCapacityUnits': 10  # WriteCapacityUnits set to 10 writes per second
        }
    )
    return table

if __name__ == '__main__':
    book_table = create_books_table()
    print("Status:", book_table.table_status)

В приведенном выше коде мы создали таблицу с именем Books; book_id - это ключ раздела, title - ключ сортировки. Далее мы определили нашу таблицу, объяснив схему ключей, хранящуюся в переменной KeySchema.

Мы также объявили типы данных атрибутов. Где "N" представляет собой число, а "S" представляет собой строку, мы также добавили переменную ProvisionedThroughput, чтобы уменьшить количество операций "read" и "write" в базе данных в секунду.

Наконец, в последнем разделе фрагмента кода мы создали экземпляр нашего класса.

Добавление образцов данных в таблицу DynamoDB

В этом разделе мы добавим примеры данных в таблицу DynamoDB. Эти данные будут записаны в формате JSON. Для начала создайте файл JSON, data.json, и добваьте следующие данные: 

[
    {
        "book_id": 1000,
        "title": "Atomic habits",
        "author": "James Clear",
        "isbn": "34526767",
        "year_of_publication": "2019"
    },
    {
        "book_id": 1001,
        "title": "Americanah",
        "author": "Chimamanda Adichie",
        "isbn": "10202223",
        "year_of_publication": "2013"
    },
    {
        "book_id": 1002,
        "title": "Teller of secrets",
        "author": "Bisi Adjapon",
        "isbn": "10201120",
        "year_of_publication": "2013"
    },
    {
        "book_id": 1003,
        "title": "Joys of motherhood",
        "author": "Buchi Emecheta",
        "isbn": "10110120",
        "year_of_publication": "1979" 
    },

    {
        "book_id": 1004,
        "title": "Purple Hibiscus",
        "author": "Chimamanda Adichie",
        "isbn": "10001241",
        "year_of_publication": "2012" 
    }
]

Теперь нам нужно загрузить эти данные, чтобы добавить их в нашу базу данных. Создайте файл Python, store_data.py, и добавьте эти строки кода:

import json 
from decimal import Decimal
import boto3 

def load_data(books, dynamodb=None):
    dynamodb = boto3.resource(
        'dynamodb')

    books_table = dynamodb.Table('Books')
    for book in books:
        book_id = (book['book_id'])
        title= book['title']

        print("Displaying book data:", book_id, title)
        books_table.put_item(Item=book)

if __name__ == '__main__':

    with open("data.json") as json_file:
        book_list = json.load(json_file, parse_float=Decimal)
    load_data(book_list)

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

Запустите следующую команду в вашем терминале, чтобы выполнить приведенный выше скрипт. 

python store_data.py

Как только скрипт будет успешно запущен, результат ваших загруженных данных будет отображен на вашем терминале.

Displaying book data: 1000 Atomic habits
Displaying book data: 1001 Americanah
Displaying book data: 1002 Teller of secrets
Displaying book data: 1003 Joys of motherhood
Displaying book data: 1004 Purple Hibiscus

Мы выполнили хорошую работу.

Операции CRUD в DynamoDB с использованием Python

Мы успешно создали таблицу, содержащую данные (элементы), и каждый из этих элементов составляет набор атрибутов. Это основные компоненты DynamoDB.

В этом разделе мы будем работать над выполнением операций CRUD с использованием элементов в нашей таблице Dynamodb.

Создание элемента

Мы будем использовать метод put_item() для добавления новых элементов в таблицу Books. Чтобы начать, создайте новый файл python, add_book.py, и добавьте следующий фрагмент кода:

import boto3

def add_book(books, dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')
    response = books_table.put_item(
        Item={
        "book_id": 1005,
        "title": "There Was a Country",
        "author": "Chinua Achebe",
        "isbn": "0143124030",
        "year_of_publication": "2012"

        }
    )


    return response

if __name__ == '__main__':
    book_resp = add_book(books='Books')
    print(book_resp)

В приведенном выше фрагменте кода мы определили функцию, которая будет добавлять элементы их нашей таблицы Dynamo. Далее используя метод put_item(), мы добавили образцы данных для таблицы DynamoDB.

Запустите скрипты в вашем терминале, чтобы добавить данные:

python add_book.py

Вы должны получить этот вывод:

{'ResponseMetadata': {'RequestId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Thu, 05 May 2022 15:00:40 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '2', 'connection': 'keep-alive', 'x-amzn-requestid': '', 'x-amz-crc32': '2745614147'}, 'RetryAttempts': 0}}

Чтение элемента

Мы также можем получить доступ к элементу (элементам) в таблице DynamoDB, используя метод get_item(). Нам нужен основной, чтобы иметь возможность получить доступ к базе данных. Основным элементом этого проекта является комбинация ключа сортировки (’title’) и ключа раздела (’book_id’).

Создайте файл python, get_book.py, и добавьте следующие строки кода: 

import boto3
from botocore.exceptions import ClientError

def get_book(book_id, title, dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')

    try:
        response = books_table.get_item(
            Key={'book_id': book_id, 'title': title})
    except ClientError as e:
            print(e.response['No item found'])
    else:
            return response['Item']

if __name__ == '__main__':
    book = get_book(1000, "Atomic habits")
    if book:
        print(book)

Из приведенного выше кода мы импортировали ClientError из пакета botocore.exceptions, который предназначен для того, чтобы помочь нам ориентироваться и обрабатывать ошибки и исключения, которые могут возникнуть при взаимодействии с AWS Boto3 SDK.

Запустите этот скрипт на вашем терминале, используя эту команду: 

python get_book.py

Вы должны получить этот вывод: 

{'year_of_publication': '2019', 'isbn': '34526767', 'book_id': Decimal('1000'), 'author': 'James Clear', 'title': 'Atomic habits'}

Выражения условий

При работе с DynamoDB вы, скорее всего, будете использовать выражение условий при изменении элементов в таблице базы данных. 

Выражение условий - это необязательные параметры, используемые для манипулирования указанными элементами в таблице DynamoDB. Выражение условий применяется с использованием операций PutItemUpdateItem и DeleteItem.

Эти операции выполняются при обновлении или удалении элементов. Операция завершается успешно только в том случае, если для значения выражения условия установлено значение true; в противном случае операция завершается с ошибкой.

В следующем разделе мы будем работать с выражениями условий для обновления и удаления элементов в нашей таблице.

Обновление элемента

Мы также можем обновить существующие данные в нашей таблице. Это делается либо путем обновления значений существующего атрибута, добавления новых атрибутов, либо путем удаления атрибутов.

В этом разделе мы обновим значение существующего атрибута, используя метод update_item(). Давайте начнем с существующего атрибута в нашей таблице:

{
    "book_id": 1000,
    "title": "Atomic habits",
    "author": "James Clear",
    "isbn": "34526767",
    "year_of_publication": "2019"
}

Создайте файл python, update_book.py, и вставьте эти строки кода:

import boto3

def update_book(book_id, title, dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')

    response = books_table.update_item(
        Key={
            'book_id' : 1001,
            'title': "Americanah"
        },
        UpdateExpression="set ISBN=:ISBN",
        ExpressionAttributeValues={':ISBN': "9780307455925"},
        ReturnValues="UPDATED_NEW"
    )
    return response

if __name__ == '__main__':
    update_response = update_book(1001, 'Americanah')
    print(update_response)

Из приведенного выше кода мы определили функцию, которая будет добавлять элементы из нашей таблицы Dynamo. Далее, используя метод update_item(), мы намерены обновить атрибут в таблице DynamoDB. Другие используемые параметры включают:

UpdateExpression: определяет атрибуты, которые необходимо обновить, и их новые значения.

ExpressionAttributeValues: это выражение содержит заменители для обновляемого атрибута или нового значения.

ReturnValues: используйте этот параметр, чтобы получить атрибуты элемента до или после их обновления. Для UpdateItem() допустимыми значениями являются NONE | ALL_OLD | UPDATED_OLD | ALL_NEW | UPDATED_NEW.

Запустите этот скрипт на вашем терминале, используя эту команду:

python update_book.py

Вывод:

{'Attributes': {'ISBN': '9780307455925'}, 'ResponseMetadata': {'RequestId': '3TJHT8856E3GRKFCPN8S5HMRQ3VV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Mon, 09 May 2022 10:26:53 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '45', 'connection': 'keep-alive', 'x-amzn-requestid': '3TJHT8856E3GRKFCPN8S5HMRQ3VV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2958762950'}, 'RetryAttempts': 0}}

Удаление элемента

Для последней операции CRUD мы будем удалять элемент из нашей таблицы, используя метод delete_item(). Вы можете либо использовать первичный ключ элемента, либо ConditionExpression для удаления элемента. Если вы хотите использовать ConditionExpression, значение выражения условия должно быть установлено в true. Однако в этом руководстве мы будем использовать как первичный ключ, так и выражение условия.

Создайте файл python, delete_book.py, и эти строки кода:

import boto3

def delete_book(book_id, title, dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')

    response = books_table.delete_item(
        Key={
            'book_id' : 1001,
            'title': "Americanah"
        },
        ConditionExpression="ISBN=:ISBN",
        ExpressionAttributeValues={':ISBN': "9780307455925"},

    )
    return response

if __name__ == '__main__':
    delete_response = delete_book(1001, 'Americanah')
    print(delete_response)

Запустите этот скрипт на своем терминале с помощью этой команды:

python delete_book.py

Вывод:

{'ResponseMetadata': {'RequestId': 'LQ2M5SKSNKAASF041VPKE6FQCFVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Mon, 09 May 2022 11:56:08 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '2', 'connection': 'keep-alive', 'x-amzn-requestid': 'LQ2M5SKSNKAASF041VPKE6FQCFVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '2745614147'}, 'RetryAttempts': 0}}

Таблицы запросов в DynamoDB

Запрос к нашей таблице базы данных возвращает каждый элемент в таблице с одним и тем же ключом раздела. Мы будем запрашивать таблицу, используя значение нашего ключа раздела, используя метод query(). Ключом раздела в этом проекте является ‘book_id’.

Давайте погрузимся!

Создайте файл python, query_table.py, и вставьте эти строки кода:

import boto3 
from boto3.dynamodb.conditions import Key 

def query_book(book_id, dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')

    response = books_table.query(
        KeyConditionExpression=Key('book_id').eq(1001)
    )
    return response['Items']

if __name__ == '__main__':
    query_id = 10001
    print(f"Book ID: {query_id}")
    books_data = query_book(query_id)
    for book_data in books_data:
       print(book_data['book_id'], ":", book_data['title'])

Запустите этот скрипт на своем терминале с помощью этой команды:

python query_table.py 

Вывод:

Book ID: 10001
1001: Americanah

Удаление таблицы

В дополнение к операциям CRUD, вы также можете удалить всю таблицу DynamoDB с помощью метода table.delete(). Все, что вам нужно сделать, это указать название таблицы, которую вы хотите удалить.

Создайте файл python, delete_table.py, и вставьте эти строки кода:

import boto3

def delete_table(dynamodb=None):
    dynamodb = boto3.resource('dynamodb')

    books_table = dynamodb.Table('Books')
    books_table.delete()

if __name__ == '__main__':
    delete_table()
    print("DynamoDB table deleted!")

Запустите этот скрипт на вашем терминале, используя эту команду:

python delete_table.py

Вывод:

DynamoDB table deleted

Вывод

Несколько операций DynamoDB можно выполнить, создав скрипт на Python с использованием AWS Boto3. В этом руководстве мы создали таблицу DynamoDB, используя Boto3 для взаимодействия с нашей базой данных и выполнения операций CRUD, запроса и удаления таблицы.

#Python #AWS
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться