Início Rápido: criar um aplicativo da API para Table com o SDK do Python e o Azure Cosmos DB

APLICA-SE A: Table

Este guia início rápido mostra como acessar a API para Table do Azure Cosmos DB em um aplicativo Python. O Azure Cosmos DB for Table é um armazenamento de dados sem esquema para que os aplicativos armazenem dados NoSQL estruturados na nuvem. Como os dados são armazenados sem esquema, as propriedades novas (colunas) são adicionadas automaticamente à tabela quando um objeto com um novo atributo é adicionado a ela. Os aplicativos Python podem acessar o Azure Cosmos DB for Table usando o pacote de SDK de Tabelas de Dados do Azure para Python.

Pré-requisitos

O aplicativo de exemplo foi escrito em Python 3.7 ou posterior, embora os princípios se apliquem a todos os aplicativos Python 3.7+. Você pode usar Visual Studio Code como um IDE.

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Aplicativo de exemplo

Você pode clonar ou baixar o aplicativo de exemplo deste tutorial no repositório https://github.com/Azure-Samples/msdocs-azure-tables-sdk-python-flask.

git clone https://github.com/Azure-Samples/msdocs-azure-tables-sdk-python-flask.git

Uma pasta de exemplo 1-starter-app e 2-completed-app estão incluídas no repositório de exemplos. O 1-starter-app tem algumas funcionalidades deixadas para você completar com linhas marcadas com "#TODO". Os snippets de código mostrados neste artigo são as adições sugeridas para concluir o 1-starter-app.

O aplicativo de exemplo concluido usa dados meteorológicos para demonstrar os recursos da API de Tabela. Os objetos que representam as observações sobre o clima são armazenados e recuperados usando a API de Tabela, incluindo o armazenamento de objetos com propriedades extras para demonstrar os recursos sem esquema da API de Tabela. A imagem a seguir mostra o aplicativo local em execução em um navegador, exibindo os dados meteorológicos armazenados no Azure Cosmos DB for Table.

Uma captura de tela do aplicativo concluído, que mostra os dados armazenados em uma tabela do Azure Cosmos DB usando a API de Tabela.

1 – Criar uma conta do Azure Cosmos DB

Primeiro, você precisa criar uma conta da API de Tabela do Azure Cosmos DB, que conterá as tabelas usadas no aplicativo. Crie uma conta por meio do portal do Azure, CLI do Azure ou Azure PowerShell.

Faça logon no portal do Azure e siga estas etapas para criar uma conta do Azure Cosmos DB.

Instruções Captura de tela
No Portal do Azure:
  1. Na caixa de pesquisa na parte superior do portal do Azure, insira "cosmos db".
  2. No menu que aparece abaixo da barra de pesquisa, em Serviços, selecione o item com o rótulo Azure Cosmos DB.
Uma captura de tela que mostra como usar a caixa de pesquisa na barra de ferramentas superior para localizar as contas do Azure Cosmos DB no Azure.
Na página Azure Cosmos DB, selecione +Criar. Uma captura de tela que mostra o local do botão Criar na página de contas do Azure Cosmos DB no Azure.
Na página Selecionar opção de API, escolha a opção Tabela do Azure. Uma captura de tela mostrando a opção da Tabela do Azure como a opção correta para selecionar.
Na página Criar Conta do Azure Cosmos DB – Tabela do Azure, preencha o formulário da seguinte maneira.
  1. Crie um grupo de recursos para a conta de armazenamento chamada rg-msdocs-tables-sdk-demo selecionando o link Criar em Grupo de recursos.
  2. Dê o nome de cosmos-msdocs-tables-sdk-demo-XYZ à conta de armazenamento, ondel XYZ são três caracteres aleatórios para criar um nome de conta exclusivo. Os nomes de contas do Azure Cosmos DB devem ter entre 3 e 44 caracteres e podem conter apenas letras minúsculas, números ou o caractere de hífen (-).
  3. Selecione a região de sua conta de armazenamento.
  4. Selecione o desempenho Standard.
  5. Selecione Taxa de transferência provisionada para este exemplo em Modo de capacidade.
  6. Selecione Aplicar em Aplicar Desconto por Nível Gratuito para este exemplo.
  7. Clique no botão Examinar e criar na parte inferior da tela e depois selecione Criar na tela de resumo para criar a conta do Azure Cosmos DB. Esse processo pode levar vários minutos.
Uma captura de tela que mostra como preencher os campos na página de criação de conta do Azure Cosmos DB.

2 – Criar uma tabela

Em seguida, você precisa criar uma tabela em sua conta do Azure Cosmos DB para que o aplicativo use. Ao contrário de um banco de dados tradicional, você só precisa especificar o nome da tabela e não as propriedades (colunas). À medida que os dados são carregados na tabela, as propriedades (colunas) são criadas automaticamente conforme necessário.

No portal do Azure, siga as etapas a seguir para criar uma tabela dentro de sua conta do Azure Cosmos DB.

Instruções Captura de tela
Na página portal do Azure, navegue até a página de visão geral da conta do Azure Cosmos DB.
  1. Você pode navegar até a página de visão geral da sua conta do Azure Cosmos DB digitando o nome (cosmos-msdocs-tables-sdk-demo-XYZ) da sua conta do Azure Cosmos DB na barra de pesquisa superior e conferindo o título de recursos.

  2. Selecione o nome da sua conta do Azure Cosmos DB para acessar a página de Visão geral.

Uma captura de tela que mostra como usar a caixa de pesquisa na barra de ferramentas superior para localizar uma conta do Azure Cosmos DB.
Na página Visão geral, selecione + Adicionar Tabela. A caixa de diálogo Nova Tabela é exibida do lado direito da página. Uma captura de tela que mostra o local do botão Adicionar Tabela.
Na caixa de diálogo Nova Tabela, preencha o formulário a seguir.
  1. Insira o nome WeatherData para a ID da Tabela. Esse valor é o nome da tabela.
  2. Selecione Manual em Taxa de transferência de tabela para este exemplo.
  3. Use o valor padrão de 400 na RU/s estimada.
  4. Selecione o botão OK para criar a tabela.
Uma captura de tela que mostra a caixa de diálogo Nova Tabela para uma tabela do Azure Cosmos DB.

3 – Obter a cadeia de conexão do Azure Cosmos DB

Para acessar as tabelas no Azure Cosmos DB, o aplicativo precisa da cadeia de conexão de tabela da conta de Armazenamento do Cosmos DB. Você pode conseguir a cadeia de conexão usando o portal do Azure, a CLI do Azure ou o Azure PowerShell.

Instruções Captura de tela
No lado esquerdo da página da conta do Azure Cosmos DB, localize o item de menu chamado Cadeias de conexão no título Segurança e selecione-o. Você será direcionado para uma página onde poderá recuperar a cadeia de conexão da conta do Azure Cosmos DB. Uma captura de tela que mostra o local do link de cadeias de conexão na página do Azure Cosmos DB.
Copie o valor da CADEIA DE CONEXÃO PRIMÁRIA para usar no aplicativo. Uma captura de tela mostrando qual cadeia de conexão você deve selecionar e usar no aplicativo.

4 – Instalar o SDK de Tabela de Dados do Azure para Python

Após criar uma conta do Azure Cosmos DB, a próxima etapa será instalar o SDK de Tabelas de Dados do Microsoft Azure para Python. Para obter detalhes sobre como instalar o SDK, veja o arquivo README.md no repositório do SDK das Tabelas de Dados para Python no GitHub.

Instale a biblioteca de clientes de Tabelas do Azure para Python com pip:

pip install azure-data-tables

Não se esqueça de instalar também o requirements.txt nas pastas 1-starter-app ou 2-completed-app .


5 – Configurar o cliente de Tabela em um arquivo .env

Copie a cadeia de conexão de conta do Azure Cosmos DB do portal do Azure e crie um objeto TableServiceClient usando a cadeia de conexão copiada. Alterne para a pasta 1-starter-app ou 2-completed-app. Independentemente do aplicativo com o qual você começa, você precisa definir variáveis de ambiente em um arquivo .env.

# Configuration Parameters
conn_str = "A connection string to an Azure Cosmos DB account."
table_name = "WeatherData"
project_root_path = "Project abs path"

O SDK do Azure se comunica com o Azure usando objetos de cliente para executar operações diferentes no Azure. O objeto TableServiceClient é usado para se comunicar com o Azure Cosmos DB for Table. Um aplicativo normalmente terá um único TableServiceClient geral e terá um TableClientpor tabela.

Por exemplo, o código a seguir cria um objeto TableServiceClient usando a cadeia de conexão a partir da variável de ambiente.

self.conn_str = os.getenv("conn_str")
self.table_service = TableServiceClient.from_connection_string(self.conn_str)

6 – Implementar operações de tabela do Azure Cosmos DB

Todas as operações de tabelas do Azure Cosmos DB para o aplicativo de exemplo são implementadas na classe TableServiceHelper localizada no arquivo auxiliar no diretório webapp. Será necessário importar a classe TableServiceClient na parte superior desse arquivo para trabalhar com objetos na biblioteca de clientes azure.data.tables para Python.

from azure.data.tables import TableServiceClient

No início da classe TableServiceHelper, crie um construtor e adicione uma variável de membro para o objeto TableClient para permitir que o objeto TableClient seja inserido na classe.

def __init__(self, table_name=None, conn_str=None):
    self.table_name = table_name if table_name else os.getenv("table_name")
    self.conn_str = conn_str if conn_str else os.getenv("conn_str")
    self.table_service = TableServiceClient.from_connection_string(self.conn_str)
    self.table_client = self.table_service.get_table_client(self.table_name)

Filtrar as linhas retornadas de uma tabela

Para filtrar as linhas retornadas de uma tabela, você pode passar uma cadeia de caracteres de filtro de estilo OData ao método query_entities. Por exemplo, para obter todas as leituras meteorológicas de Chicago entre a meia-noite de 1º de julho de 2021 e a meia-noite de 2 de julho de 2021 (inclusive), você passaria a cadeia de caracteres de filtro a seguir.

PartitionKey eq 'Chicago' and RowKey ge '2021-07-01 12:00 AM' and RowKey le '2021-07-02 12:00 AM'

É possível exibir os operadores de filtro OData relacionados no site azure-data-tables na seção Gravar filtros.

Quando o parâmetro request.args é passado ao método query_entity na classe TableServiceHelper, ele cria uma cadeia de caracteres de filtro para cada valor de propriedade não nulo. Em seguida, ele cria uma cadeia de caracteres de filtro combinada unindo todos os valores com uma cláusula "and". A cadeia de caracteres de filtro combinada é passada ao método query_entities no objeto TableClient e somente as linhas correspondentes à cadeia de caracteres de filtro são retornadas. Você pode usar um método semelhante no código para criar cadeias de caracteres de filtro adequadas a seu aplicativo.

def query_entity(self, params):
    filters = []
    if params.get("partitionKey"):
        filters.append("PartitionKey eq '{}'".format(params.get("partitionKey")))
    if params.get("rowKeyDateStart") and params.get("rowKeyTimeStart"):
        filters.append("RowKey ge '{} {}'".format(params.get("rowKeyDateStart"), params.get("rowKeyTimeStart")))
    if params.get("rowKeyDateEnd") and params.get("rowKeyTimeEnd"):
        filters.append("RowKey le '{} {}'".format(params.get("rowKeyDateEnd"), params.get("rowKeyTimeEnd")))
    if params.get("minTemperature"):
        filters.append("Temperature ge {}".format(params.get("minTemperature")))
    if params.get("maxTemperature"):
        filters.append("Temperature le {}".format(params.get("maxTemperature")))
    if params.get("minPrecipitation"):
        filters.append("Precipitation ge {}".format(params.get("minPrecipitation")))
    if params.get("maxPrecipitation"):
        filters.append("Precipitation le {}".format(params.get("maxPrecipitation")))
    return list(self.table_client.query_entities(" and ".join(filters)))

Inserir dados usando um objeto TableEntity

A maneira mais simples de adicionar dados a uma tabela é usar um objeto TableEntity. Neste exemplo, mapeamos os dados de um objeto de modelo de entrada para um objeto TableEntity. Mapeamos as propriedades no objeto de entrada que representam o nome da estação meteorológica e a data/hora de observação para as propriedades PartitionKey e RowKey, respectivamente, que juntas formam uma chave exclusiva para a linha na tabela. Em seguida, mapeamos as propriedades extras no objeto de modelo de entrada para propriedades de dicionário no objeto TableEntity. Por fim, usamos o método create_entity do objeto TableClient para inserir dados na tabela.

Modifique a função insert_entity do aplicativo de exemplo para conter o código a seguir.

def insert_entity(self):
    entity = self.deserialize()
    return self.table_client.create_entity(entity)
    
@staticmethod
def deserialize():
    params = {key: request.form.get(key) for key in request.form.keys()}
    params["PartitionKey"] = params.pop("StationName")
    params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
    return params

Executar upsert de dados usando um objeto TableEntity

Se você tentar inserir uma linha em uma tabela com uma combinação de chave de partição/chave de linha que já existe nessa tabela, você receberá um erro. Por isso, geralmente é melhor usar o método upsert_entity em vez de create_entity ao adicionar linhas a uma tabela. Se a combinação de chave/linha de partição determinada já existir na tabela, o método upsert_entity atualizará a linha atual. Caso contrário, a linha é adicionada à tabela.

def upsert_entity(self):
    entity = self.deserialize()
    return self.table_client.upsert_entity(entity)
    
@staticmethod
def deserialize():
    params = {key: request.form.get(key) for key in request.form.keys()}
    params["PartitionKey"] = params.pop("StationName")
    params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
    return params

Inserir ou executar upsert de dados com propriedades variáveis

Esta é uma das vantagens de usar o Azure Cosmos DB for Table: se o objeto carregado em uma tabela contiver propriedades novas, elas serão adicionadas automaticamente à tabela e os valores serão armazenados no Cosmos DB. Não é necessário executar instruções DDL como ALTER TABLE para adicionar colunas como em um banco de dados tradicional.

Com esse modelo, o aplicativo tem flexibilidade para lidar com fontes que adicionam dados ou modificam quais dados devem ser capturados ao longo do tempo, ou quando entradas diferentes fornecem dados diferentes ao aplicativo. No aplicativo de exemplo, podemos simular uma estação meteorológica que envia não apenas os dados meteorológicos base, mas também alguns valores extras. Quando um objeto com essas novas propriedades é armazenado na tabela pela primeira vez, as propriedades correspondentes (colunas) são adicionadas automaticamente à tabela.

Para inserir ou executar upsert desse objeto usando a API de Tabela, mapeie as propriedades do objeto expansível para um objeto TableEntity e use o método apropriado, create_entity ou upsert_entity, no objeto TableClient.

No aplicativo de exemplo, a função upsert_entity também pode implementar a função de inserir ou executar upsert de dados com propriedades variáveis

def insert_entity(self):
    entity = self.deserialize()
    return self.table_client.create_entity(entity)

def upsert_entity(self):
    entity = self.deserialize()
    return self.table_client.upsert_entity(entity)

@staticmethod
def deserialize():
    params = {key: request.form.get(key) for key in request.form.keys()}
    params["PartitionKey"] = params.pop("StationName")
    params["RowKey"] = "{} {}".format(params.pop("ObservationDate"), params.pop("ObservationTime"))
    return params

Atualizar uma entidade

Para atualizar entidades, chame o método update_entity do objeto TableClient.

No aplicativo de exemplo, esse objeto é passado ao método upsert_entity na classe TableClient. Ele atualiza esse objeto de entidade e usa o método upsert_entity para salvar as atualizações no banco de dados.

def update_entity(self):
    entity = self.update_deserialize()
    return self.table_client.update_entity(entity)
    
@staticmethod
def update_deserialize():
    params = {key: request.form.get(key) for key in request.form.keys()}
    params["PartitionKey"] = params.pop("StationName")
    params["RowKey"] = params.pop("ObservationDate")
    return params

Remover uma entidade

Para remover uma entidade de uma tabela, chame o método delete_entity no objeto TableClient com a chave de partição e a chave de linha do objeto.

def delete_entity(self):
    partition_key = request.form.get("StationName")
    row_key = request.form.get("ObservationDate")
    return self.table_client.delete_entity(partition_key, row_key)

7 – Executar o código

Execute o aplicativo de exemplo para interagir com o Azure Cosmos DB for Table. Por exemplo, a partir da pasta 2-completed-app, com os requisitos instalados, você pode usar:

python3 run.py webapp

Confira o arquivo README.md na raiz do repositório de exemplo para obter mais informações sobre como executar o aplicativo de exemplo.

Na primeira vez que você executar o aplicativo, não haverá dados porque a tabela estará vazia. Use qualquer um dos botões na parte superior do aplicativo para adicionar dados à tabela.

Uma captura de tela do aplicativo que mostra o local dos botões usados para inserir dados no Azure Cosmos DB usando a API de Tabela.

Quando você seleciona o botão Inserir Usando Entidade de Tabela, é aberta uma caixa de diálogo para a inserção ou o upsert de uma nova linha usando um objeto TableEntity.

Uma captura de tela do aplicativo que mostra a caixa de diálogo para inserir dados usando um objeto TableEntity.

Quando você seleciona o botão Inserir usando dados expansíveis, é aberta uma caixa de diálogo para a inserção de um objeto com propriedades personalizadas. Isso demonstra como o Azure Cosmos DB for Table adiciona automaticamente propriedades (colunas) à tabela quando necessário. Use o botão Adicionar Campo Personalizado para adicionar uma ou mais propriedades novas e demonstrar essa funcionalidade.

Uma captura de tela do aplicativo que mostra a caixa de diálogo para inserir dados usando um objeto com campos personalizados.

Use o botão Inserir dados de exemplo para carregar alguns dados de exemplo na tabela do Azure Cosmos DB.

  • Para a pasta de exemplo 1-starter-app, você precisará pelo menos concluir o código da função submit_transaction para que a inserção dos dados de exemplo funcione.

  • Os dados de exemplo são carregados a partir de um arquivo sample_data.json . A variável project_root_path.env informa ao aplicativo onde encontrar esse arquivo. Por exemplo, se você estiver executando o aplicativo na pasta 1-starter-app ou 2-completed-app, defina project_root_path como "" (em branco).

Uma captura de tela do aplicativo que mostra o local do botão de inserção de dados de exemplo.

Selecione o item Filtrar Resultados no menu superior para abrir a página Resultados do Filtro. Nesta página, preencha os critérios de filtro para demonstrar como criar uma cláusula de filtro e passá-la ao Azure Cosmos DB for Table.

Uma captura de tela do aplicativo que mostra a página de resultados do filtro e realça o item de menu usado para navegar até a página.

Limpar os recursos

Quando você terminar o aplicativo de exemplo, remova todos os recursos do Azure relacionados a este artigo de sua conta do Azure. Para remover todos os recursos, exclua o grupo de recursos.

Para excluir um grupo de recursos, siga as instruções a seguir no portal do Azure.

Instruções Captura de tela
Para acessar o grupo de recursos, na barra de pesquisa, digite o nome do grupo de recursos. Na guia Grupos de Recursos, selecione o nome do grupo de recursos. Captura de tela que mostra como pesquisar um grupo de recursos.
Selecione Excluir grupo de recursos na barra de ferramentas, na parte superior da página do grupo de recursos. Uma captura de tela que mostra a localização do botão Excluir grupo de recursos.
Uma caixa de diálogo será exibida à direita da tela solicitando que você confirme a exclusão do grupo de recursos.
  1. Digite o nome completo do grupo de recursos na caixa de texto para confirmar a exclusão, conforme instruído.
  2. Selecione o botão Excluir na parte inferior da página.
Uma captura de tela que mostra a caixa de diálogo de confirmação para excluir um grupo de recursos.

Próximas etapas

Neste início rápido, você aprendeu como criar uma conta do BD Cosmos do Azure, como criar uma tabela usando o Data Explorer e como executar um aplicativo. Agora você pode consultar os dados usando a API de Tabela.