Metadata-Version: 2.1
Name: dynolayer
Version: 0.4.1
Summary: O DynoLayer é uma ferramenta poderosa que simplifica e agiliza o acesso e manipulação de dados no Amazon DynamoDB, baseada no padrão Active Record.
Home-page: https://github.com/kauelima21/dynolayer
Author: Kauê Leal de Lima
Author-email: kaueslim@gmail.com
License: MIT License
Keywords: dynolayer,dynamodb,active record,aws lambda
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: boto3
Requires-Dist: pytz
Requires-Dist: python-dotenv

# DynoLayer

O **DynoLayer** Ã© uma ferramenta poderosa que simplifica e agiliza o acesso e manipulaÃ§Ã£o de dados no Amazon DynamoDB. Baseada no padrÃ£o Active Record, esta biblioteca oferece uma abstraÃ§Ã£o intuitiva para interagir com tabelas no DynamoDB, permitindo operaÃ§Ãµes de CRUD (Create, Read, Update, Delete) de forma fÃ¡cil e natural.

## InstalaÃ§Ã£o

Para usar o pacote basta instalar atravÃ©s do gerenciador de dependÃªncias de sua preferÃªncia.

```sh
pip install dynolayer
```

ou

```sh
pipenv install dynolayer
```

## Exemplos

Para mais exemplos, consulte a pasta [docs](https://github.com/kauelima21/dynolayer/tree/main/docs)

Para iniciar, primeiro vocÃª precisa criar a sua model herdando a classe *DynoLayer*. O nome da tabela e os atributos obrigatÃ³rios sÃ£o os Ãºnicos campos requeridos, os demais jÃ¡ possuem um valor padrÃ£o.

```python
from dynolayer import DynoLayer


class User(DynoLayer):
    def __init__(self) -> None:
        super().__init__('users', [])
```

Por padrÃ£o, o timezone utilizado Ã© o ```America/Sao_Paulo```. Para alterar isso basta adicionar a variÃ¡vel de ambiente **TIMESTAMP_TIMEZONE** com o valor desejado.

```sh
TIMESTAMP_TIMEZONE='US/Eastern'
```

O mesmo se aplica para a regiÃ£o e para o uso local do dynamodb. Caso as variÃ¡veis abaixo nÃ£o existam, os valores padrÃ£o serÃ£o **sa-east-1** e o dynamodb da da aws na regiÃ£o utilizada.

```sh
REGION='us-east-1'
LOCAL_ENDPOINT='http://localhost:8000'
```

### Save

Para criar um registro, Ã© preciso instanciar a model e atribuir valor as suas propriedades. Depois basta rodar um **save()** para salvar no banco!

```python
user = User()

user.full_name = 'John Doe'
user.email = 'john@mail.com'
user.stars = 5
user.phones = [
    '11 91234-5678',
    '10 95678-1234',
]

if user.save():
    print('UsuÃ¡rio adicionado com sucesso!')
```

O mesmo mÃ©todo Ã© usado para atualizar o registro, basta possuir a chave de partiÃ§Ã£o e os dados que precisam ser alterados.

```python
user = User()

user.id = 'meu-id-55'
user.email = 'john.doe@email.com' # altera o email

user.save() # atualiza o registro para o novo email
```

### Find By Id

Para buscar um registro pela chave de partiÃ§Ã£o, se usa o mÃ©todo **find_by_id()**. O mesmo vai retornar a instancia da model com os atributos buscados, mantendo o Active Record e possibilitando a execuÃ§Ã£o de outras instruÃ§Ãµes, como o update que vimos a pouco.

```python
user = User().find_by_id('meu-id-55')
user.stars = 17
print(f'O usuÃ¡rio {user.full_name} possui {user.stars} estrelas!')

user.save()
```

### Find

Para as demais consultas, como uma busca geral (scan) ou uma busca com filtro, o mÃ©todo utilizado Ã© o **find()** e os mÃ©todos subsequentes para formar um *Query Builder*.

```python
# busca todos os produtos
products = Product().find().fetch() 

# busca todos os usuÃ¡rios que estÃ£o com o status COMPLETED
completed_users = User().find(
    '#st = :st',
    {':st': 'COMPLETED'},
    {'#st': 'status'}
).fetch()

# busca todos os usuÃ¡rios com limite de 10
users = User().find().limit(10).fetch() 
```

Ã‰ importante destacar que o scan possui um limite na quantidade de dados que retorna, e para trabalhar com isso basta assinalar o parÃ¢metro *paginate_through_results* como ```True``` no mÃ©todo **fetch()**.

```python
# busca todos os produtos paginando o resultado da consulta no DynamoDB
products = Product().find().fetch(True)
```

### Find By
Para os casos de consultas com filtro em determinada propriedade que nÃ£o seja uma chave de partiÃ§Ã£o, pode-se usar o mÃ©todo **find_by**. Para verificar a contagem de itens recebidos ao realizar o fetch (apÃ³s o *find* ou *find_by*), basta usar a propriedade **get_count**

```python
users = User()
online_users = users.find_by('status', '=', 'online').fetch(True)
print(f'{users.get_count} online no momento!')
```

### Query By
Para os casos de consultas com filtro em determinada chave de partiÃ§Ã£o, pode-se usar o mÃ©todo **query_by**.

```python
users = User()
online_users = users.query_by('status', '=', 'online').fetch(True)
print(f'{users.get_count} online no momento!')
```

### Order
Serve para ordenar de acordo com determinado atributo, podendo tambÃ©m trazer a resposta de form crescente ou decrescente, a depender do valor que for passado no segundo argumento que por padrÃ£o Ã© True e retorna de maneira crescente.

```python
users = User()
online_users = users.find_by('status', '=', 'online').order('first_name').fetch(True)
print(f'{users.get_count} online no momento!')
```

### Count
Caso queira contar o total de itens na tabela ou operaÃ§Ã£o que vocÃª fizer sem retornar os dados registrados nela, basta substituir o mÃ©todo **fetch()** por **count()**

```python
users = User()
online_users = users.find_by('status', '=', 'online').order('first_name').count()
print(f'{online_users} online no momento!')
```

### Fetch
Por default retorna os dados como um dict, mas ao passar o argumento object como True ele retorna os registros como um objeto DynoLayer.

```python
users = User().find_by('status', '=', 'online').order('first_name').fetch(object=True)
print(users[0].name)
```

### Destroy

Para remover um registro, basta obter a sua chave de partiÃ§Ã£o e executar o mÃ©todo **destroy()** em seguida.

```python
user = User().find_by_id('meu-id-55')

if user.destroy():
    print('UsuÃ¡rio removido com sucesso!')
```
