

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Driver Amazon QLDB para Python
<a name="getting-started.python"></a>

**Importante**  
Aviso de fim do suporte: os clientes existentes poderão usar o Amazon QLDB até o final do suporte em 31/07/2025. Para obter mais detalhes, consulte [Migrar um Amazon QLDB Ledger para o Amazon](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/) Aurora PostgreSQL.

Para trabalhar com dados em seu livro contábil, você pode se conectar ao Amazon QLDB a partir do seu aplicativo Python usando um driver fornecido. AWS Os tópicos a seguir descrevem como começar a usar o driver QLDB para Python.

**Topics**
+ [Recursos para driver](#getting-started.python.resources)
+ [Pré-requisitos](#getting-started.python.prereqs)
+ [Instalação](#getting-started.python.install)
+ [Tutorial de início rápido](driver-quickstart-python.md)
+ [Referência de Cookbook](driver-cookbook-python.md)

## Recursos para driver
<a name="getting-started.python.resources"></a>

Para obter mais informações sobre a funcionalidade suportada pelo driver Python, consulte os recursos a seguir:
+ Referência de API: [3.x](https://amazon-qldb-driver-python.readthedocs.io/en/latest/), [2.x](https://amazon-qldb-driver-python.readthedocs.io/en/v2.0.2/)
+ [Código-fonte do driver (GitHub)](https://github.com/awslabs/amazon-qldb-driver-python)
+ [Exemplo de código-fonte do aplicativo (GitHub)](https://github.com/aws-samples/amazon-qldb-dmv-sample-python)
+ [Exemplos de código do Amazon Ion](ion.code-examples.md)

## Pré-requisitos
<a name="getting-started.python.prereqs"></a>

Antes de começar a usar o driver QLDB para Python, você deverá fazer o seguinte:

1. Siga as instruções AWS de configuração em[Acessar o Amazon QLDB](accessing.md). Essa transmissão inclui o seguinte:

   1. Inscreva-se em AWS.

   1. Crie um usuário com as permissões adequadas para QLDB.

   1. Conceda acesso programático para desenvolvimento.

1. Instale uma das seguintes versões do Python no site de downloads do [Python](https://www.python.org/downloads/):
   + **3.6 ou posterior **: driver QLDB para Python v3
   + **3.4 ou posterior **: driver QLDB para Python v2

1. Configure suas AWS credenciais e seu padrão Região da AWS. Para obter instruções, consulte [Início rápido](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html#configuration) na AWS SDK para Python (Boto3) documentação.

   Para obter uma lista completa das regiões disponíveis, consulte [endpoints e cotas Amazon QLDB](https://docs.aws.amazon.com/general/latest/gr/qldb.html) em *Referência geral da AWS*.

Em seguida, você pode baixar o aplicativo completo de amostra do tutorial ou instalar somente o driver em um projeto Python e executar exemplos de códigos curtos.
+ Para instalar o driver QLDB e AWS SDK para Python (Boto3) o em um projeto existente, vá para. [Instalação](#getting-started.python.install)
+ Para configurar um projeto e executar exemplos de códigos curtos que demonstram transações básicas de dados em um ledger, consulte o [Tutorial de início rápido](driver-quickstart-python.md).
+ Para executar exemplos mais detalhados das operações da API de dados e gerenciamento no aplicativo de amostra completo do tutorial, consulte [Tutorial do Python](getting-started.python.tutorial.md).

## Instalação
<a name="getting-started.python.install"></a>

O QLDB suporta as seguintes versões do driver e suas dependências Python.


****  

| Versão do driver | Versão do Python | Status | Data da versão mais recente | 
| --- | --- | --- | --- | 
| [2.x](https://pypi.org/project/pyqldb/2.0.2/) | 3.4 ou posterior | Lançamento de produção | 7 de maio de 2020 | 
| [3.x](https://pypi.org/project/pyqldb/) | 3.6 ou posterior | Lançamento de produção | 28 de outubro de 2021 | 

Para instalar o driver QLDB a partir do PyPI usando `pip` (um gerenciador de pacotes para Python), digite o seguinte na linha de comando.

------
#### [ 3.x ]

```
pip install pyqldb
```

------
#### [ 2.x ]

```
pip install pyqldb==2.0.2
```

------

A instalação do driver também instala suas dependências, incluindo os pacotes [AWS SDK para Python (Boto3)](https://aws.amazon.com/sdk-for-python) e [Amazon Ion](ion.md).

**Como usar o driver para se conectar a um ledger**

Depois, você pode importar o driver e usá-lo para se conectar a um ledger. Os exemplos de código Python a seguir mostram como criar uma sessão para um nome de livro contábil especificado.

------
#### [ 3.x ]

```
from pyqldb.driver.qldb_driver import QldbDriver
qldb_driver = QldbDriver(ledger_name='testLedger')

for table in qldb_driver.list_tables():
    print(table)
```

------
#### [ 2.x ]

```
from pyqldb.driver.pooled_qldb_driver import PooledQldbDriver

qldb_driver = PooledQldbDriver(ledger_name='testLedger')
qldb_session = qldb_driver.get_session()

for table in qldb_session.list_tables():
    print(table)
```

------

Para exemplos de código curto de como executar transações básicas de dados em um ledger, consulte o [Referência de Cookbook](driver-cookbook-python.md).

# Driver Amazon QLDB para Python: tutorial de início rápido
<a name="driver-quickstart-python"></a>

**Importante**  
Aviso de fim do suporte: os clientes existentes poderão usar o Amazon QLDB até o final do suporte em 31/07/2025. Para obter mais detalhes, consulte [Migrar um Amazon QLDB Ledger para o Amazon](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/) Aurora PostgreSQL.

Neste tutorial, você aprenderá como configurar um aplicativo simples usando a versão mais recente do driver QLDB da Amazon para Python. Este guia inclui etapas para instalação do driver e exemplos de códigos curtos de operações básicas de *criação, leitura, atualização e exclusão* (CRUD). Para obter exemplos mais detalhados que demonstram essas operações em um aplicativo de amostra completo, consulte o [Tutorial do Python](getting-started.python.tutorial.md).

**Topics**
+ [Pré-requisitos](#driver-quickstart-python.prereqs)
+ [Etapa 1: configurar o projeto do](#driver-quickstart-python.step-1)
+ [Etapa 2: Inicializar o driver](#driver-quickstart-python.step-2)
+ [Etapa 3: Crie uma tabela e um índice](#driver-quickstart-python.step-3)
+ [Etapa 4: Inserir um documento](#driver-quickstart-python.step-4)
+ [Etapa 5: consultar o documento](#driver-quickstart-python.step-5)
+ [Etapa 6: Atualize o documento](#driver-quickstart-python.step-6)
+ [Executar o aplicativo completo](#driver-quickstart-python.complete)

## Pré-requisitos
<a name="driver-quickstart-python.prereqs"></a>

Antes de iniciar, certifique-se de fazer o seguinte:

1. Complete a [Pré-requisitos](getting-started.python.md#getting-started.python.prereqs) Para o driver Python, caso ainda não o tenha feito. Isso inclui se inscrever AWS, conceder acesso programático para desenvolvimento e instalar o Python versão 3.6 ou posterior.

1. Crie um ledger chamado `quick-start`.

   Para saber como criar um ledger, consulte [Operações básicas para ledgers do Amazon QLDB](ledger-management.basics.md) ou [Etapa 1: criar um novo ledger](getting-started-step-1.md) em *Conceitos básicos do console*.

## Etapa 1: configurar o projeto do
<a name="driver-quickstart-python.step-1"></a>

Primeiro, configure seu projeto Python.

**nota**  
Se você usa um IDE que tenha atributos para automatizar essas etapas de configuração, pode pular para [Etapa 2: Inicializar o driver](#driver-quickstart-python.step-2).

1. Crie uma pasta para o seu aplicativo.

   ```
   $ mkdir myproject
   $ cd myproject
   ```

1. Para instalar o driver QLDB para Python a partir do PyPI, digite o comando `pip` a seguir.

   ```
   $ pip install pyqldb
   ```

   A instalação do driver também instala suas dependências, incluindo os pacotes [AWS SDK para Python (Boto3)](https://aws.amazon.com/sdk-for-net) e [Amazon Ion](ion.md).

1. Crie um novo arquivo chamado `app.py`.

   Em seguida, adicione incrementalmente os exemplos de código nas etapas a seguir para experimentar algumas operações básicas de CRUD. Ou você pode pular o step-by-step tutorial e, em vez disso, executar o [aplicativo completo](#driver-quickstart-python.complete).

## Etapa 2: Inicializar o driver
<a name="driver-quickstart-python.step-2"></a>

Inicialize uma instância do driver que se conecta ao ledger chamado `quick-start`. Adicione o seguinte código ao arquivo `app.py`.

```
from pyqldb.config.retry_config import RetryConfig
from pyqldb.driver.qldb_driver import QldbDriver

# Configure retry limit to 3
retry_config = RetryConfig(retry_limit=3)

# Initialize the driver
print("Initializing the driver")
qldb_driver = QldbDriver("quick-start", retry_config=retry_config)
```

## Etapa 3: Crie uma tabela e um índice
<a name="driver-quickstart-python.step-3"></a>

O exemplo de código a seguir mostra como executar as instruções `CREATE TABLE` e `CREATE INDEX`.

Adicione o código a seguir que cria uma tabela chamada `People` e um índice para o campo `lastName` nessa tabela. Os [índices](ql-reference.create-index.md) são necessários para otimizar o desempenho da consulta e ajudar a limitar as exceções de conflitos de [controle de simultaneidade otimista (OCC)](concurrency.md).

```
def create_table(transaction_executor):
    print("Creating a table")
    transaction_executor.execute_statement("Create TABLE People")

def create_index(transaction_executor):
    print("Creating an index")
    transaction_executor.execute_statement("CREATE INDEX ON People(lastName)")

# Create a table
qldb_driver.execute_lambda(lambda executor: create_table(executor))

# Create an index on the table
qldb_driver.execute_lambda(lambda executor: create_index(executor))
```

## Etapa 4: Inserir um documento
<a name="driver-quickstart-python.step-4"></a>

O exemplo de código a seguir mostra como executar uma instrução `INSERT`. O QLDB suporta a linguagem de consulta [partiQL](ql-reference.md) (compatível com SQL) e o formato de dados [Amazon Ion ](ion.md) (superconjunto de JSON).

Adicione o código a seguir que insere um documento na tabela `People`.

```
def insert_documents(transaction_executor, arg_1):
    print("Inserting a document")
    transaction_executor.execute_statement("INSERT INTO People ?", arg_1)

# Insert a document
doc_1 = { 'firstName': "John",
          'lastName': "Doe",
          'age': 32,
        }

qldb_driver.execute_lambda(lambda x: insert_documents(x, doc_1))
```

Este exemplo usa um ponto de interrogação (`?`) como um marcador variável para passar as informações do documento para a instrução. O método `execute_statement` suporta valores nos tipos Amazon Ion e nos tipos nativos do Python.

**dica**  
Para inserir vários documentos usando uma única instrução [INSERT](ql-reference.insert.md), você pode passar um parâmetro do tipo [lista](driver-working-with-ion.md#driver-ion-list) para a instrução da seguinte maneira.  

```
# people is a list
transaction_executor.execute_statement("INSERT INTO Person ?", people)
```
Você não coloca o marcador variável (`?`) entre colchetes angulares duplos (`<<...>>`) ao passar uma lista. Nas instruções manuais do PartiQL, colchetes angulares duplos denotam uma coleção não ordenada conhecida como *bolsa*.

## Etapa 5: consultar o documento
<a name="driver-quickstart-python.step-5"></a>

O exemplo de código a seguir mostra como executar uma instrução `SELECT`.

Adicione o código a seguir que insere um documento da tabela `People`.

```
def read_documents(transaction_executor):
    print("Querying the table")
    cursor = transaction_executor.execute_statement("SELECT * FROM People WHERE lastName = ?", 'Doe')

    for doc in cursor:
        print(doc["firstName"])
        print(doc["lastName"])
        print(doc["age"])

# Query the table
qldb_driver.execute_lambda(lambda executor: read_documents(executor))
```

## Etapa 6: Atualize o documento
<a name="driver-quickstart-python.step-6"></a>

O exemplo de código a seguir mostra como executar uma instrução `UPDATE`.

1. Adicione o código a seguir que insere um documento na tabela `People`, atualizando `age` para `42`.

   ```
   def update_documents(transaction_executor, age, lastName):
       print("Updating the document")
       transaction_executor.execute_statement("UPDATE People SET age = ? WHERE lastName = ?", age, lastName)
   
   # Update the document
   age = 42
   lastName = 'Doe'
   
   qldb_driver.execute_lambda(lambda x: update_documents(x, age, lastName))
   ```

1. Consulte a tabela novamente para ver o valor atualizado.

   ```
   # Query the updated document
   qldb_driver.execute_lambda(lambda executor: read_documents(executor))
   ```

1. Para executar o aplicativo, insira o comando a seguir do diretório do seu projeto.

   ```
   $ python app.py
   ```

## Executar o aplicativo completo
<a name="driver-quickstart-python.complete"></a>

O exemplo de código a seguir é a versão completa do aplicativo `app.py`. Em vez de executar as etapas anteriores individualmente, você também pode copiar e executar esse exemplo de código do início ao fim. Este aplicativo demonstra algumas operações básicas do CRUD no ledger denominado `quick-start`.

**nota**  
Antes de executar esse código, verifique se você ainda não tem uma tabela ativa chamada `People` no ledger `quick-start`.

```
from pyqldb.config.retry_config import RetryConfig
from pyqldb.driver.qldb_driver import QldbDriver

def create_table(transaction_executor):
    print("Creating a table")
    transaction_executor.execute_statement("CREATE TABLE People")

def create_index(transaction_executor):
    print("Creating an index")
    transaction_executor.execute_statement("CREATE INDEX ON People(lastName)")

def insert_documents(transaction_executor, arg_1):
    print("Inserting a document")
    transaction_executor.execute_statement("INSERT INTO People ?", arg_1)

def read_documents(transaction_executor):
    print("Querying the table")
    cursor = transaction_executor.execute_statement("SELECT * FROM People WHERE lastName = ?", 'Doe')
                                                                                                                                          
    for doc in cursor:
        print(doc["firstName"])
        print(doc["lastName"])
        print(doc["age"])

def update_documents(transaction_executor, age, lastName):
    print("Updating the document")
    transaction_executor.execute_statement("UPDATE People SET age = ? WHERE lastName = ?", age, lastName)

# Configure retry limit to 3
retry_config = RetryConfig(retry_limit=3)

# Initialize the driver
print("Initializing the driver")
qldb_driver = QldbDriver("quick-start", retry_config=retry_config)

# Create a table
qldb_driver.execute_lambda(lambda executor: create_table(executor))

# Create an index on the table
qldb_driver.execute_lambda(lambda executor: create_index(executor))

# Insert a document
doc_1 = { 'firstName': "John",
          'lastName': "Doe",
          'age': 32,
        }

qldb_driver.execute_lambda(lambda x: insert_documents(x, doc_1))

# Query the table
qldb_driver.execute_lambda(lambda executor: read_documents(executor))

# Update the document
age = 42
lastName = 'Doe'

qldb_driver.execute_lambda(lambda x: update_documents(x, age, lastName))

# Query the table for the updated document
qldb_driver.execute_lambda(lambda executor: read_documents(executor))
```

Para executar o aplicativo completo, insira o comando a seguir do diretório do seu projeto.

```
$ python app.py
```

# Driver Amazon QLDB para Python: referência do livro de receitas
<a name="driver-cookbook-python"></a>

**Importante**  
Aviso de fim do suporte: os clientes existentes poderão usar o Amazon QLDB até o final do suporte em 31/07/2025. Para obter mais detalhes, consulte [Migrar um Amazon QLDB Ledger para o Amazon](https://aws.amazon.com/blogs/database/migrate-an-amazon-qldb-ledger-to-amazon-aurora-postgresql/) Aurora PostgreSQL.

Este guia de referência mostra casos de uso comuns do driver Amazon QLDB para Python. Ele fornece exemplos de código Python que demonstram como usar o driver para executar operações básicas CRUD (*create, read, update, delete*). Também inclui exemplos de código para processamento de dados do Amazon Ion. Além disso, este guia destaca as práticas recomendadas para tornar as transações idempotentes e implantar restrições de exclusividade.

**nota**  
Quando aplicável, alguns casos de uso têm exemplos de código diferentes para cada versão principal com suporte do driver QLDB para Python.

**Contents**
+ [Importação do driver](#cookbook-python.importing)
+ [Instanciação do driver](#cookbook-python.instantiating)
+ [Operações de CRUD](#cookbook-python.crud)
  + [Criar tabelas](#cookbook-python.crud.creating-tables)
  + [Criar índices](#cookbook-python.crud.creating-indexes)
  + [Ler documentos](#cookbook-python.crud.reading)
    + [Usar parâmetros de consulta](#cookbook-python.reading-using-params)
  + [Inserir documentos](#cookbook-python.crud.inserting)
    + [Como inserir vários documentos em uma instrução](#cookbook-python.crud.inserting.multiple)
  + [Como atualizar documentos](#cookbook-python.crud.updating)
  + [Como excluir documentos](#cookbook-python.crud.deleting)
  + [Como executar várias instruções em uma transação](#cookbook-python.crud.multi-statement)
  + [Lógica de novas tentativas](#cookbook-python.crud.retry-logic)
  + [Implementação de restrições de exclusividade](#cookbook-python.crud.uniqueness-constraints)
+ [Como trabalhar com o Amazon Ion](#cookbook-python.ion)
  + [Importar o módulo Ion](#cookbook-python.ion.import)
  + [Criação de tipos de Ion](#cookbook-python.ion.creating-types)
  + [Obter um despejo de binário Ion](#cookbook-python.ion.getting-binary)
  + [Obter um despejo de texto Ion](#cookbook-python.ion.getting-text)

## Importação do driver
<a name="cookbook-python.importing"></a>

O exemplo de código a seguir importa o driver.

------
#### [ 3.x ]

```
from pyqldb.driver.qldb_driver import QldbDriver
import amazon.ion.simpleion as simpleion
```

------
#### [ 2.x ]

```
from pyqldb.driver.pooled_qldb_driver import PooledQldbDriver
import amazon.ion.simpleion as simpleion
```

------

**nota**  
Este exemplo também importa o pacote Amazon Ion (`amazon.ion.simpleion`). Você precisa desse pacote para processar dados de íons ao executar algumas operações de dados nesta referência. Para saber mais, consulte [Como trabalhar com o Amazon Ion](#cookbook-python.ion).

## Instanciação do driver
<a name="cookbook-python.instantiating"></a>

O exemplo de código a seguir cria uma instância do driver que se conecta a um nome de ledger especificado usando as configurações padrão.

------
#### [ 3.x ]

```
qldb_driver = QldbDriver(ledger_name='vehicle-registration')
```

------
#### [ 2.x ]

```
qldb_driver = PooledQldbDriver(ledger_name='vehicle-registration')
```

------

## Operações de CRUD
<a name="cookbook-python.crud"></a>

O QLDB *executa operações de criação, leitura, atualização e exclusão* (CRUD) como parte de uma transação.

**Atenção**  
Como prática recomendada, torne suas transações de gravação estritamente idempotentes.

**Tornar as transações idempotentes**

Recomendamos que você torne as transações de gravação idempotentes para evitar efeitos colaterais inesperados no caso de novas tentativas. Uma transação é *idempotente* se puder ser executada várias vezes e produzir resultados idênticos a cada vez.

Por exemplo, considere uma transação que insere um documento em uma tabela chamada `Person`. A transação deve primeiro verificar se o documento já existe ou não na tabela. Sem essa verificação, a tabela pode acabar com documentos duplicados.

Suponha que o QLDB confirme com sucesso a transação no lado do servidor, mas o tempo do cliente expire enquanto espera por uma resposta. Se a transação não for idempotente, o mesmo documento poderá ser inserido mais de uma vez no caso de uma nova tentativa.

**Usar índices para evitar varreduras completas da tabela**

Também recomendamos executar instruções com uma cláusula de predicado `WHERE` usando um operador de *igualdade* em um campo indexado ou em um ID de documento, por exemplo, `WHERE indexedField = 123` ou `WHERE indexedField IN (456, 789)`. Sem essa pesquisa indexada, o QLDB precisa fazer uma varredura de tabela, o que pode levar a tempos limite de transação ou conflitos *otimistas de controle de simultaneidade* (OCC).

Para obter mais informações sobre OCC, consulte [Modelo de simultaneidade do Amazon QLDB](concurrency.md).

**Transações criadas implicitamente**

O método [pyqldb.driver.qldb\$1driver.execute\$1lambda](https://amazon-qldb-driver-python.readthedocs.io/en/stable/reference/driver/qldb_driver.html#pyqldb.driver.qldb_driver.QldbDriver.execute_lambda) aceita uma função do lambda que recebe uma instância de [pyqldb.execution.executor.Executor](https://amazon-qldb-driver-python.readthedocs.io/en/stable/reference/execution/executor.html#pyqldb.execution.executor.Executor), que você pode usar para executar instruções. A instância de `Executor` envolve uma transação criada implicitamente.

Você pode executar instruções na função do Lambda usando o método do executor da transação [execute\$1statement](https://amazon-qldb-driver-python.readthedocs.io/en/stable/reference/execution/executor.html#pyqldb.execution.executor.Executor.execute_statement). O driver confirma implicitamente a transação quando a função do Lambda retorna.

**nota**  
O método `execute_statement` suporta os tipos Amazon Ion e os tipos nativos do Python. Se você passar um tipo nativo do Python como argumento para `execute_statement`, o driver o converterá em um tipo Ion usando o módulo `amazon.ion.simpleion` (desde que a conversão para o determinado tipo de dados do Python seja suportada). Para ver os tipos de dados e as regras de conversão compatíveis, consulte o [código-fonte simpleion](https://ion-python.readthedocs.io/en/latest/_modules/amazon/ion/simpleion.html).

As seções a seguir mostram como executar operações CRUD básicas, especificar a lógica de repetição personalizada e implementar restrições de exclusividade.

**Contents**
+ [Criar tabelas](#cookbook-python.crud.creating-tables)
+ [Criar índices](#cookbook-python.crud.creating-indexes)
+ [Ler documentos](#cookbook-python.crud.reading)
  + [Usar parâmetros de consulta](#cookbook-python.reading-using-params)
+ [Inserir documentos](#cookbook-python.crud.inserting)
  + [Como inserir vários documentos em uma instrução](#cookbook-python.crud.inserting.multiple)
+ [Como atualizar documentos](#cookbook-python.crud.updating)
+ [Como excluir documentos](#cookbook-python.crud.deleting)
+ [Como executar várias instruções em uma transação](#cookbook-python.crud.multi-statement)
+ [Lógica de novas tentativas](#cookbook-python.crud.retry-logic)
+ [Implementação de restrições de exclusividade](#cookbook-python.crud.uniqueness-constraints)

### Criar tabelas
<a name="cookbook-python.crud.creating-tables"></a>

```
def create_table(transaction_executor):
    transaction_executor.execute_statement("CREATE TABLE Person")

qldb_driver.execute_lambda(lambda executor: create_table(executor))
```

### Criar índices
<a name="cookbook-python.crud.creating-indexes"></a>

```
def create_index(transaction_executor):
    transaction_executor.execute_statement("CREATE INDEX ON Person(GovId)")

qldb_driver.execute_lambda(lambda executor: create_index(executor))
```

### Ler documentos
<a name="cookbook-python.crud.reading"></a>

```
# Assumes that Person table has documents as follows:
# { "GovId": "TOYENC486FH", "FirstName": "Brent" }

def read_documents(transaction_executor):
    cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = 'TOYENC486FH'")

    for doc in cursor:
        print(doc["GovId"]) # prints TOYENC486FH
        print(doc["FirstName"]) # prints Brent

qldb_driver.execute_lambda(lambda executor: read_documents(executor))
```

#### Usar parâmetros de consulta
<a name="cookbook-python.reading-using-params"></a>

O exemplo de código a seguir usa um parâmetro de consulta do tipo nativo.

```
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH')
```

O exemplo de código a seguir usa um parâmetro de consulta do tipo Ion.

```
name = ion.loads('Brent')
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE FirstName = ?", name)
```

O exemplo de código a seguir usa múltiplos parâmetros de consulta.

```
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ? AND FirstName = ?", 'TOYENC486FH', "Brent")
```

O exemplo de código a seguir usa uma lista de parâmetros de consulta.

```
gov_ids = ['TOYENC486FH','ROEE1','YH844']
cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId IN (?,?,?)", *gov_ids)
```

**nota**  
Quando você executa uma consulta sem uma pesquisa indexada, ela invoca uma verificação completa da tabela. Neste exemplo, recomendamos ter um [índice](ql-reference.create-index.md) no campo `GovId` para otimizar o desempenho. Sem um índice em `GovId`, as consultas podem ter mais latência e também podem levar a exceções de conflitos de OCC ou a tempos limite de transação.

### Inserir documentos
<a name="cookbook-python.crud.inserting"></a>

Os exemplos de código a seguir inserem os tipos de dados nativos.

```
def insert_documents(transaction_executor, arg_1):
    # Check if doc with GovId:TOYENC486FH exists
    # This is critical to make this transaction idempotent
    cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH')
    # Check if there is any record in the cursor
    first_record = next(cursor, None)

    if first_record:
        # Record already exists, no need to insert
        pass
    else:
        transaction_executor.execute_statement("INSERT INTO Person ?", arg_1)

doc_1 = { 'FirstName': "Brent",
          'GovId': 'TOYENC486FH',
        }

qldb_driver.execute_lambda(lambda executor: insert_documents(executor, doc_1))
```

Os exemplos de código a seguir inserem os tipos de dados Ion.

```
def insert_documents(transaction_executor, arg_1):
    # Check if doc with GovId:TOYENC486FH exists
    # This is critical to make this transaction idempotent
    cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", 'TOYENC486FH')
    # Check if there is any record in the cursor
    first_record = next(cursor, None)

    if first_record:
        # Record already exists, no need to insert
        pass
    else:
        transaction_executor.execute_statement("INSERT INTO Person ?", arg_1)

doc_1 = { 'FirstName': 'Brent',
          'GovId': 'TOYENC486FH',
        }

# create a sample Ion doc
ion_doc_1 = simpleion.loads(simpleion.dumps(doc_1)))

qldb_driver.execute_lambda(lambda executor: insert_documents(executor, ion_doc_1))
```

Essa transação insere um documento na tabela `Person`. Antes de inserir, ele primeiro verifica se o documento já existe na tabela. **Essa verificação torna a transação idempotente por natureza.** Mesmo que você execute essa transação várias vezes, ela não causará efeitos colaterais indesejados.

**nota**  
Neste exemplo, recomendamos ter um índice no campo `GovId` para otimizar o desempenho. Sem um índice em `GovId`, as instruções podem ter mais latência e também podem levar a exceções de conflitos de OCC ou a tempos limite de transação.

#### Como inserir vários documentos em uma instrução
<a name="cookbook-python.crud.inserting.multiple"></a>

Para inserir vários documentos usando uma única instrução [INSERT](ql-reference.insert.md), você pode passar um parâmetro do tipo [lista](driver-working-with-ion.md#driver-ion-list) para a instrução da seguinte maneira.

```
# people is a list
transaction_executor.execute_statement("INSERT INTO Person ?", people)
```

Você não coloca o marcador variável (`?`) entre colchetes angulares duplos (`<<...>>`) ao passar uma lista. Nas instruções manuais do PartiQL, colchetes angulares duplos denotam uma coleção não ordenada conhecida como *bolsa*.

### Como atualizar documentos
<a name="cookbook-python.crud.updating"></a>

Os exemplos de código a seguir usam tipos de dados nativos.

```
def update_documents(transaction_executor, gov_id, name):
    transaction_executor.execute_statement("UPDATE Person SET FirstName = ?  WHERE GovId = ?", name, gov_id)

gov_id = 'TOYENC486FH'
name = 'John'

qldb_driver.execute_lambda(lambda executor: update_documents(executor, gov_id, name))
```

O exemplo de código a seguir usa os tipos de dados Ion.

```
def update_documents(transaction_executor, gov_id, name):
    transaction_executor.execute_statement("UPDATE Person SET FirstName = ? WHERE GovId = ?", name, gov_id)

# Ion datatypes
gov_id = simpleion.loads('TOYENC486FH')
name = simpleion.loads('John')

qldb_driver.execute_lambda(lambda executor: update_documents(executor, gov_id, name))
```

**nota**  
Neste exemplo, recomendamos ter um índice no campo `GovId` para otimizar o desempenho. Sem um índice em `GovId`, as instruções podem ter mais latência e também podem levar a exceções de conflitos de OCC ou a tempos limite de transação.

### Como excluir documentos
<a name="cookbook-python.crud.deleting"></a>

Os exemplos de código a seguir usam tipos de dados nativos.

```
def delete_documents(transaction_executor, gov_id):
    cursor = transaction_executor.execute_statement("DELETE FROM Person WHERE GovId = ?", gov_id)

gov_id = 'TOYENC486FH'

qldb_driver.execute_lambda(lambda executor: delete_documents(executor, gov_id))
```

O exemplo de código a seguir usa os tipos de dados Ion.

```
def delete_documents(transaction_executor, gov_id):
    cursor = transaction_executor.execute_statement("DELETE FROM Person WHERE GovId = ?", gov_id)

# Ion datatypes
gov_id = simpleion.loads('TOYENC486FH')

qldb_driver.execute_lambda(lambda executor: delete_documents(executor, gov_id))
```

**nota**  
Neste exemplo, recomendamos ter um índice no campo `GovId` para otimizar o desempenho. Sem um índice em `GovId`, as instruções podem ter mais latência e também podem levar a exceções de conflitos de OCC ou a tempos limite de transação.

### Como executar várias instruções em uma transação
<a name="cookbook-python.crud.multi-statement"></a>

```
# This code snippet is intentionally trivial. In reality you wouldn't do this because you'd
# set your UPDATE to filter on vin and insured, and check if you updated something or not.

def do_insure_car(transaction_executor, vin):
    cursor = transaction_executor.execute_statement(
        "SELECT insured FROM Vehicles WHERE vin = ? AND insured = FALSE", vin)
    first_record = next(cursor, None)
    if first_record:
        transaction_executor.execute_statement(
            "UPDATE Vehicles SET insured = TRUE WHERE vin = ?", vin)
        return True
    else:
        return False

def insure_car(qldb_driver, vin_to_insure):
    return qldb_driver.execute_lambda(
        lambda executor: do_insure_car(executor, vin_to_insure))
```

### Lógica de novas tentativas
<a name="cookbook-python.crud.retry-logic"></a>

O método `execute_lambda` do driver tem um mecanismo de repetição integrado que repete a transação se ocorrer uma exceção que pode ser repetida (como tempos limite ou conflitos de OCC).

------
#### [ 3.x ]

O número máximo de tentativas de repetição e a estratégia de recuo são configuráveis.

O limite de repetição padrão é `4`, e a estratégia de recuo padrão é [recuo exponencial e Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) com uma base de `10` milissegundos. Você pode definir a configuração de repetição por instância de driver e também por transação usando uma instância de [pyqldb.config.retry\$1config. RetryConfig](https://amazon-qldb-driver-python.readthedocs.io/en/stable/reference/config/retry_config.html#pyqldb.config.retry_config.RetryConfig).

O exemplo de código a seguir especifica a lógica de repetição com um limite de repetição personalizado e uma estratégia de recuo personalizada para uma instância do driver.

```
from pyqldb.config.retry_config import RetryConfig
from pyqldb.driver.qldb_driver import QldbDriver

# Configuring retry limit to 2
retry_config = RetryConfig(retry_limit=2)
qldb_driver = QldbDriver("test-ledger", retry_config=retry_config)

# Configuring a custom backoff which increases delay by 1s for each attempt.
def custom_backoff(retry_attempt, error, transaction_id):
    return 1000 * retry_attempt

retry_config_custom_backoff = RetryConfig(retry_limit=2, custom_backoff=custom_backoff)
qldb_driver = QldbDriver("test-ledger", retry_config=retry_config_custom_backoff)
```

O exemplo de código a seguir especifica a lógica de repetição com um limite de repetição personalizado e uma estratégia de recuo personalizada para uma instância do lambda. Essa configuração para `execute_lambda` substitui a lógica de repetição definida para a instância do driver.

```
from pyqldb.config.retry_config import RetryConfig
from pyqldb.driver.qldb_driver import QldbDriver

# Configuring retry limit to 2
retry_config_1 = RetryConfig(retry_limit=4)
qldb_driver = QldbDriver("test-ledger", retry_config=retry_config_1)

# Configuring a custom backoff which increases delay by 1s for each attempt.
def custom_backoff(retry_attempt, error, transaction_id):
    return 1000 * retry_attempt

retry_config_2 = RetryConfig(retry_limit=2, custom_backoff=custom_backoff)

# The config `retry_config_1` will be overriden by `retry_config_2`
qldb_driver.execute_lambda(lambda txn: txn.execute_statement("CREATE TABLE Person"), retry_config_2)
```

------
#### [ 2.x ]

O número máximo de tentativas de repetição pode ser configurado. Você pode configurar o limite de novas tentativas definindo a propriedade `retry_limit` ao inicializar `PooledQldbDriver`.

O limite padrão de novas tentativas é `4`.

------

### Implementação de restrições de exclusividade
<a name="cookbook-python.crud.uniqueness-constraints"></a>

O QLDB não oferece suporte a índices exclusivos, mas você pode implementar esse comportamento em seu aplicativo.

Suponha que você queira implementar uma restrição de exclusividade no campo `GovId` da tabela `Person`. Para fazer isso, você pode escrever uma transação que faça o seguinte:

1. Afirme que a tabela não tem documentos existentes com um `GovId` especificado.

1. Insira o documento se a afirmação for aprovada.

Se uma transação concorrente passar simultaneamente pela declaração, somente uma das transações será confirmada com sucesso. A outra transação falhará com uma exceção de conflito de OCC.

O exemplo de código a seguir mostra como implementar essa lógica de restrição de exclusividade.

```
def insert_documents(transaction_executor, gov_id, document):
    # Check if doc with GovId = gov_id exists
    cursor = transaction_executor.execute_statement("SELECT * FROM Person WHERE GovId = ?", gov_id)
    # Check if there is any record in the cursor
    first_record = next(cursor, None)

    if first_record:
        # Record already exists, no need to insert
        pass
    else:
        transaction_executor.execute_statement("INSERT INTO Person ?", document)

qldb_driver.execute_lambda(lambda executor: insert_documents(executor, gov_id, document))
```

**nota**  
Neste exemplo, recomendamos ter um índice no campo `GovId` para otimizar o desempenho. Sem um índice em `GovId`, as instruções podem ter mais latência e também podem levar a exceções de conflitos de OCC ou a tempos limite de transação.

## Como trabalhar com o Amazon Ion
<a name="cookbook-python.ion"></a>

As seções a seguir mostram como usar o módulo Amazon Ion para processar dados do Ion.

**Contents**
+ [Importar o módulo Ion](#cookbook-python.ion.import)
+ [Criação de tipos de Ion](#cookbook-python.ion.creating-types)
+ [Obter um despejo de binário Ion](#cookbook-python.ion.getting-binary)
+ [Obter um despejo de texto Ion](#cookbook-python.ion.getting-text)

### Importar o módulo Ion
<a name="cookbook-python.ion.import"></a>

```
import amazon.ion.simpleion as simpleion
```

### Criação de tipos de Ion
<a name="cookbook-python.ion.creating-types"></a>

O exemplo de código a seguir cria um objeto Ion a partir do texto Ion.

```
ion_text = '{GovId: "TOYENC486FH", FirstName: "Brent"}'
ion_obj = simpleion.loads(ion_text)

print(ion_obj['GovId']) # prints TOYENC486FH
print(ion_obj['Name']) # prints Brent
```

O exemplo de código a seguir cria um objeto Ion a partir de um `dict` Python.

```
a_dict = { 'GovId': 'TOYENC486FH',
           'FirstName': "Brent"
         }
ion_obj = simpleion.loads(simpleion.dumps(a_dict))

print(ion_obj['GovId']) # prints TOYENC486FH
print(ion_obj['FirstName']) # prints Brent
```

### Obter um despejo de binário Ion
<a name="cookbook-python.ion.getting-binary"></a>

```
# ion_obj is an Ion struct
print(simpleion.dumps(ion_obj)) # b'\xe0\x01\x00\xea\xee\x97\x81\x83\xde\x93\x87\xbe\x90\x85GovId\x89FirstName\xde\x94\x8a\x8bTOYENC486FH\x8b\x85Brent'
```

### Obter um despejo de texto Ion
<a name="cookbook-python.ion.getting-text"></a>

```
# ion_obj is an Ion struct
print(simpleion.dumps(ion_obj, binary=False)) # prints $ion_1_0 {GovId:'TOYENC486FH',FirstName:"Brent"}
```

Para obter mais informações sobre como trabalhar com o Ion, consulte a [documentação do Amazon Ion](http://amzn.github.io/ion-docs/) em GitHub. Para obter mais exemplos de código sobre como trabalhar com o Ion no QLDB, consulte [Como trabalhar com tipos de dados do Amazon Ion no Amazon QLDB](driver-working-with-ion.md).