top of page
Foto do escritorReginaldo Silva

Azure Function para Analytics - Binding - Azure SQL - Disparando um evento via INSERT INTO

Fala dataholics, esse post faz parte da série sobre Azure Functions para Analytics, no post de hoje veremos como disparar nossa Azure Function através de eventos num banco de dados Azure SQL Server, veremos também sobre Bindings e uma demonstração bem legal.


Se ainda não viu, dá uma conferida nos posts anteriores:


No post de hoje criaremos um ambiente com SQL Server na nuvem e 2 tabelas, iremos monitorar eventos de DML (INSERT, UPDATE e DELETE) em uma tabela, quando esse evento acontecer nossa Azure Function será disparada, ela irá ler uma API e gravar dados de volta para o SQL Server.



O que veremos nesse post:

  • Triggers e Bindings

  • Azure SQL Binding

  • Disparando um evento no SQL

  • Demostração

  • Resumo


 

Triggers e Bindings


Nos posts anteriores vimos dois modelos de triggers diferentes, uma com agendamento e outra via HTTP, ou seja, trigger é a maneira que nossa Azure Function será disparada, ela só pode ser acionada por 1 tipo de evento, seja ele por HTTP, eventos numa fila, arquivos caindo no Storage, eventos em bancos de dados, a trigger define o método de acionamento da sua Function, toda Function precisa ter somente uma trigger definida.


Já os Bindings, é uma maneira de conectar nossa Function com outros serviços, exemplo, conectar nossa function com o SQL Server, Storage Account, Kafka, etc.

Ela é uma maneira simplificada de criar essas conexões, evitando a necessidade de instalar componentes e fixar os acessos via código.


Os bindings não são obrigatórios, então você pode criar sua conexão manualmente, instalando os drivers necessários e criando as conexões via código.


Os Bindings possuem 2 direções, IN (Input) e out (Output), como o próprio nome diz, isso significa que os Bindings do tipo IN são os que disparam as functions (TRIGGERS), ou seja, nossa trigger sempre tera um binding do tipo IN.


O binding output são para devolver o resultado para um serviço, exemplo, escrever o resultado numa Storage Account, usaremos um Binding de Azure Storage Account do tipo Out.


Temos uma variedade bem grande de bindings, dá uma olhada nessa lista:


No post de hoje usaremos o binding de Azure SQL e ao final do post as coisas ficaram mais claras, você pode voltar no post 1, onde fizemos uma escrita no Storage sem Binding, verá que precisei instalar as bibliotecas e criar manualmente a conexão e escrita no storage.

 

Azure SQL Binding


Como já entendemos o intuito dos bindings, agora falaremos especificamente do Azure SQL, com esse binding temos 3 opções, as opções padrão de IN e OUT, mas agora temos uma opção nova ainda em preview que podemos usar para disparar nossa function sempre que uma operação de DML ocorrer em nossas tabelas, isso pode ser útil para muitos cenários.


Essa funcionalidade que está em preview utiliza uma feature chamada CHANGE TRACKING do SQL Server para rastrear as mudanças que ocorreram na nossa tabela, essa feature é como se fosse uma parente do famoso CDC, embora, ela tenha outras finalidades então possui menos informações do que a feature do CDC, não entraremos em detalhes sobre o Change Tracking aqui, o que você precisa saber é que ela cria um rastreamento das alterações em nossas tabelas e o binding do Azure SQL usara essas informações de rastreio para disparar nossa Azure Function.


Basicamente trabalha da seguinte maneira:

Loop infinito {

1. Faz uma query na tabela de rastreio no SQL Server para verificar se há novas mudanças (DML)

2. Se houver mudanças dispara a Azure Function

3. Espera alguns milissegundos e checa novamente por mudanças, esse tempo de espera é definido em Sql_Trigger_PollingIntervalMs

}


Para nossa demostração, criaremos 2 tabelas simples e habilitaremos o Change Tracking em uma delas.


A ideia aqui é inserir dados na tabela filaCEP (apenas CPF e CEP), esse INSERT irá disparar a Azure Function através do binding de Input, a nossa function fará uma requisição na nossa API de CEP do post anterior, e gravara os dados na tabela RetornoCEP usando o binding de Output.

 

Criando nossa Azure Function

Se você está acompanhando os outros posts, notara que estou usando a mesma Azure Function (Function App) para todas as functions que estamos criando, elas estão separadas apenas por pastas, falaremos mais sobre essa organização em outros posts.


Basicamente nossa Function é composta por 2 arquivos:

function.json: Arquivo de configuração onde é definido os bindings

__init__.py: Código da nossa function


Claro que para a Azure Function todo tem outros arquivos importantes que expliquei no primeiro post.


Detalhe muito importante para sua Azure Function funcionar:

É necessário ajustar o arquivo hosts.sjon com esses valores, caso contrario, não irá funcionar.


No arquivo function.json temos essa definição:


Veja como é simples criar uma conexão com nosso banco de dados Azure SQL, simplesmente definindo nos bindings, nesse caso estou usando uma tabela, mas podemos usar queries SQL também.

Detalhe sobre o parâmetro connectionStringSetting o valor dele vem do nosso arquivo de configuração local.settings.json quando estamos rodando localmente, quando estamos dentro do Function App vem do application settings e podemos inclusive colocar esse valor numa Key Vault.


Exemplo para rodar na Function App no Azure:

Exemplo para rodar localmente:


Agora veremos nosso código:


Nesse primeiro bloco olharemos nos parâmetros de entrada da função MAIN, note que ela recebe um changes (Input definido nos bindings no arquivo function.json) e retornoCEP que devolve um SqlRow (Output definido nos bindings), isso já é o suficiente para criamos nossa conexão com o banco de dados de forma simples.


No segundo bloco estamos recuperando o valor recebido no Changes (veremos em breve sua estrutura) e transformando em um JSON, no terceiro bloco extraímos 2 campos desse Json.


Nessa parte final do código, logo após preencher as variáveis, executaremos uma chamada na nossa API de CEP e pegar esses valores e gravar na tabela do Azure SQL utilizando a operação SET().


O código estará disponível no Github, vejamos ele funcionando na prática agora.


Para essa demostração, usarei esse exemplo:

Iremos inserir um registro na tabela filaCEP, fazer um select nela e 5 segundos depois fazer um select na tabela retornoCEP, esses 5 segundos é o tempo da nossa function identificar a mudança no SQL, disparar a trigger, fazer a requisição na API e devolver os dados para a tabela retornoCEP, abaixo foto da tabela vazia.


Veja com detalhes nesse vídeo a ideia do delay de 5 segundos é exatamente aguardar o tempo da Azure Function ser disparada e retornar os dados para a tabela de retornoCEP.


Olhando na data de log, podemos notar que o tempo total para execução dessa function é de 3 segundos.

Basicamente esta acontecendo tudo isso por detrás dos panos:

  1. Function fn_azure_sql identificou um novo INSERT e disparou

  2. Fez a leitura dos dados alterados, e fez uma chamada na API de CEP

  3. A nossa API de CEP executou uma query no PostgreSQL para retornar os dados, essa query SQL tem com 4 JOINS

  4. Dado retornado para a fn_azure_sql e inserido no SQL Server


Aqui estão os logs da function, podemos ver o SQL Changes retornado pelo Azure SQL, depois algumas informações, assim como a chamada na API de CEP e Status code 200 de sucesso e por fim a mensagem GRAVADO COM SUCESSO.

Detalhe sobre os logs gerados pelo Change Tracking, o campo Operation informa qual foi a operação no registro e dentro do Item temos os dados referente a ele:

'Operation': 0 - Insert
'Operation': 1 - Update
'Operation': 2 - Delete

Se mais de um registro for modificado no mesmo batch, todos eles vêm dentro do campo Item.

 

Resumo


Sabemos que Azure Functions são excelentes para reagir a eventos, com a lista de bindings apresentada no início do post podemos reagir a diversos eventos, como, por exemplo, ficar escutando um tópico no Kafka, ou ficar esperando um arquivo ser escrito numa pasta do Storage, ou receber uma requisição HTTP de um webhook, as possibilidades são muitas, logo Azure Function acaba sendo extremante útil em diversos cenários.


No post de hoje mostrei um pouco sobre Bindings, pois, usaremos mais nos próximos posts, também vimos ser possível reagir a eventos DML em tabelas do nosso Azure SQL (feature em preview), que pode ser útil para diversos cenários.


Ah, Reginaldo, mas daria para fazer com Logic Apps também né?

Sim, mostrei nesse post uma automação utilizando Logic App.

Contudo, veremos que Azure Function pode trazer maior flexibilidade e por ser Python podemos integrar e versionar com nossos projetos, uma das grandes vantagens que veremos em breve é, como manipular tabelas no Delta Lake sem Spark.


Fica ligado nos próximos posts, tem muita coisa legal para falarmos ainda.


Fiquem bem e até a próxima.


Link Github:


Referências:




118 visualizações0 comentário

Comentarios


Post: Blog2 Post
bottom of page