Hoje gostaria de compartilhar com vocês uma situação que me deparei ao criar um fluxo de dados no Apache Beam.
As condições de carga de dados devem ser cuidadosamente planejadas para evitar desperdício de recursos e, dependendo das regras de negócio, devem ser implementadas de uma ou de outra forma.
Neste caso específico, eu estava lidando com UPSERT do Apache Beam para o Big Query. Fazer insert table é muito simples em qualquer tabela ou arquivo de dados. Porém, quando falamos de Big Data, envolvemos diferentes ferramentas e ambientes. Então, em muitos casos, fazer um update não é uma tarefa tão simples.
Me deparei com um problema inusitado no Apache Beam, algo muito comum na vida de um engenheiro de dados: dados nulos. Dados nulos não são úteis para ninguém, mas nem sempre eles podem ser expurgados do processamento. Quando a regra de negócio exige que eles fiquem à disposição, é preciso tratá-los. Geralmente, prefiro usar valores default para datas, inteiros, strings e floats. Mas quando as regras de negócio exigem o contrário, podemos nos deparar com situações inusitadas.
Uma dessas situações que me deparei foi ao fazer uma carga de dados através de um pipeline Beam para uma tabela do Big Query. Ao fazer o insert, não tive nenhum problema em subir campos com valores nulos. No entanto, ao fazer o primeiro update, os problemas começaram. Vasculhando daqui, vasculhando dali, as condições foram se ajeitando. Entretanto, nenhuma sintaxe conseguia resolver o problema de subir valores nulos em um update e por uma razão muito simples: Python trata valores nulos como None, que é um objeto único que é usado como o valor de retorno padrão para funções que não retornam um valor explícito. Já em SQL, o valor especial que indica a falta de um valor válido em uma coluna de uma tabela ou em uma expressão é NULL.
Este era o problema que eu estava enfrentando. Por mais que tentasse, não conseguia fazer alterar os dados na tabela de destino. Tentei e tentei, mas nada. Foram diversas abordagens, algumas retornavam erro, outras nada, mas os dados desatualizados se mantinham firmes no Big Query.
Felizmente, quando descobrimos que as sintaxes não são tão compatíveis como gostaríamos, começamos a pensar fora da caixa. Para encontrar a solução, descobri que existe uma fronteira fictícia em fluxo de dados, que é quando os dados cruzam a fronteira da sintaxe Py para a sintaxe SQL. Em algum momento, isso tem que acontecer, não é mesmo? Neste momento, os valores que são recebidos como None devem ser alterados para NULL antes de serem escritos no Big Query. Ao perceber esse padrão, foi fácil implementar um comando que alterasse os valores None para NULL e o problema foi resolvido.
Desta forma, ao implementar a função de transformação no pipeline, adicionamos um comando que altera os valores None para NULL antes de escrevê-los no Big Query. Isso resolveu o problema de subir valores nulos em um update e os dados puderam ser atualizados corretamente na tabela de destino.
Na imagem abaixo, podemos ver a função definida que trata o código e o comando de transformação que trata os valores no pipeline. Por padrão, todos os valores nulos são convertidos para None, mas com essa solução, agora podemos lidar adequadamente com valores nulos em um ambiente Big Data e garantir a integridade dos dados.
Abaixo podemos ver o codigo executado na transformação, que percorre as linha retornando valores nulos para NULL para ser interpretado pelo SQL do Big Query. Desta forma conseguimos atualizar dados para NULL no Big Query usando o Apache Beam.
Em resumo, o texto relata um problema encontrado ao fazer um UPSERT com o Apache Beam para o Big Query e como foi solucionado através da descoberta da fronteira fictícia em fluxo de dados. O problema em questão era que Python trata valores nulos como None, enquanto em SQL, o valor especial que indica a falta de um valor válido em uma coluna de uma tabela ou em uma expressão é NULL. Ao implementar um comando que alterasse os valores None para NULL antes de escrevê-los no Big Query, o problema foi resolvido e os dados puderam ser atualizados corretamente na tabela de destino. Essa solução possibilita lidar adequadamente com valores nulos em um ambiente Big Data e garantir a integridade dos dados.