Как смоделировать AWS DynamoDB локально на Python с помощью moto 5Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как смоделировать AWS DynamoDB локально на Python с помощью moto 5

Сообщение Anonymous »

Я хочу создать класс, представляющий соединение dynamodb, который я могу использовать локально для имитации поведения DynamoDB без необходимости фактического обращения к сервису AWS.
Я хочу использовать его во время разработки (не только для запуска тестов) и использовать этот класс для создания таблицы, которая существует во время выполнения программы, и делать запросы к ней так же, как я бы делал настоящую динамо-таблицу с реальным соединением
Я использую boto3 v1.34.162 и moto v5.0.15
На данный момент вот что у меня получилось:

Код: Выделить всё

import boto3
from moto import mock_aws

@mock_aws
class MyDbClient:
def __init__(self):
self.dynamodb = boto3.client('dynamodb')
self.table_name = 'ExampleTable'
self.create_table()

def create_table(self):
table_params = {
'TableName': self.table_name,
'KeySchema': [
{'AttributeName': 'id', 'KeyType': 'HASH'},
],
'AttributeDefinitions': [
{'AttributeName': 'id', 'AttributeType': 'S'},
],
'ProvisionedThroughput': {
'ReadCapacityUnits': 5,
'WriteCapacityUnits': 5,
}
}

print(f"Creating table {self.table_name}...")
self.dynamodb.create_table(**table_params)

print(f"Waiting for table {self.table_name} to exist...")
waiter = self.dynamodb.get_waiter('table_exists')
waiter.wait(TableName=self.table_name)

print(f"Table {self.table_name} is now active.")

tables = self.dynamodb.list_tables()['TableNames']
print("Existing tables:", tables)

def put_item_in_table(self, item):
self.dynamodb.put_item(
TableName=self.table_name,
Item={
'id': {'S': item['id']},
'name': {'S': item['name']},
'description': {'S': item['description']}
}
)

def get_item_from_table(self, key):
response = self.dynamodb.get_item(
TableName=self.table_name,
Key={
'id': {'S': key['id']}
}
)
print(response)

if __name__ == "__main__":
db_client = MyDbClient()

item_to_put = {
'id': '123',
'name': 'ExampleName',
'description': 'This is a sample item'
}
db_client.put_item_in_table(item_to_put)

key_to_get = {'id': '123'}
db_client.get_item_from_table(key_to_get)

Декоратор @mock_aws должен быть тем, что мне нужно, но при его выполнении я получаю следующую ошибку: botocore.Exceptions.ClientError: произошла ошибка (404) при вызове операция GetRoleCredentials: еще не реализована, когда выполнение программы доходит до вызова create_table.
Вот также полная трассировка стека:

Код: Выделить всё

(venv) ⏺ 15:19:16 ~/Dev/sandbox $ python main.py

Creating table ExampleTable...
Traceback (most recent call last):
File "/Users/jovan/Dev/sandbox/main.py", line 60, in 
db_client = MyDbClient()
^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/main.py", line 9, in __init__
self.create_table()
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/moto/core/models.py", line 122, in wrapper
result = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/main.py", line 27, in create_table
self.dynamodb.create_table(**table_params)
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/client.py", line 569, in _api_call
return self._make_api_call(operation_name, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/client.py", line 1005, in _make_api_call
http, parsed_response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/client.py", line 1029, in _make_request
return self._endpoint.make_request(operation_model, request_dict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/endpoint.py", line 119, in make_request
return self._send_request(request_dict, operation_model)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/endpoint.py", line 196, in _send_request
request = self.create_request(request_dict, operation_model)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/endpoint.py", line 132, in create_request
self._event_emitter.emit(
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/hooks.py", line 412, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/hooks.py", line 256, in emit
return self._emit(event_name, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/hooks.py", line 239, in _emit
response = handler(**kwargs)
^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/signers.py", line 105, in handler
return self.sign(operation_name, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/signers.py", line 188, in sign
auth = self.get_auth_instance(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/signers.py", line 306, in get_auth_instance
frozen_credentials = credentials.get_frozen_credentials()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 634, in get_frozen_credentials
self._refresh()
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 522, in _refresh
self._protected_refresh(is_mandatory=is_mandatory_refresh)
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 538, in _protected_refresh
metadata = self._refresh_using()
^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 685, in fetch_credentials
return self._get_cached_credentials()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 695, in _get_cached_credentials
response = self._get_credentials()
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/credentials.py", line 2160,  in _get_credentials
response = client.get_role_credentials(**kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/client.py", line 569, in _api_call
return self._make_api_call(operation_name, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jovan/Dev/sandbox/venv/lib/python3.12/site-packages/botocore/client.py", line 1023, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (404) when calling the GetRoleCredentials operation: Not yet implemented
Еще одна вещь, которую я пробовал, — это индивидуально обернуть __init__, put_item_in_table и get_item_from_table декоратором @mock_aws. это НЕ работает, поскольку в этом случае среда макета aws создается заново каждый раз, когда вызывается какая-либо из этих функций, и, следовательно, созданная динамо-таблица не сохраняется между вызовами (что является полной противоположностью тому, что мне нужно)
Если возможно, я бы хотел просто положиться на библиотеки boto3 и moto. Я знаю, что aws localstack существует как инструмент, но это излишне для того, чего я пытаюсь достичь, и я бы не хотел его использовать


Подробнее здесь: https://stackoverflow.com/questions/791 ... ith-moto-5
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как смоделировать AWS DynamoDB локально на Python с помощью moto 5
    Anonymous » » в форуме Python
    0 Ответы
    34 Просмотры
    Последнее сообщение Anonymous
  • Невозможно подключиться к AWS dynamodb с помощью laravel с помощью kitar/laravel-dynamodb
    Anonymous » » в форуме Php
    0 Ответы
    39 Просмотры
    Последнее сообщение Anonymous
  • Использование AWS Moto с макетом Python для написания модульных тестов
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • AWS Athena с Python – можно ли издеваться над Moto, продолжая тестировать sql?
    Anonymous » » в форуме Python
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Moto, похоже, не издевается над взаимодействиями AWS в питтере
    Anonymous » » в форуме Python
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»