Использование 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.
Предпоссылки:
- Учетная запись AWS
- Базовые знания о DynamoDB
- Python
- Операционная система: 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. Выражение условий применяется с использованием операций PutItem
, UpdateItem
и 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, запроса и удаления таблицы.