O PySpark sempre ofereceu APIs SQL e Python maravilhosas para consultar dados. A partir do Databricks Runtime 15.2 e Apache Spark 4.0, as consultas parametrizadas oferecem maneiras seguras e expressivas de consultar dados com SQL usando paradigmas de programação Pythonic.
Este post explica como fazer consultas parametrizadas com PySpark e quando isso é um bom padrão de design para seu código.
Parâmetros são úteis para tornar seu código Spark mais fácil de reutilizar e testar. Eles também incentivam boas práticas de codificação. Este post demonstrará as duas maneiras diferentes de parametrizar consultas PySpark:
Vamos ver como usar ambos os tipos de consultas parametrizadas PySpark e explorar por que a funcionalidade integrada é melhor do que outras alternativas.
Consultas parametrizadas incentivam o padrão "não se repita" (DRY), facilitam testes unitários e tornam o SQL mais fácil de reutilizar. Elas também previnem ataques de injeção de SQL, que podem representar vulnerabilidades de segurança.
Pode ser tentador copiar e colar grandes trechos de SQL ao escrever consultas semelhantes. Consultas parametrizadas incentivam a abstração de padrões e a escrita de código com o padrão DRY.
Consultas parametrizadas também são mais fáceis de testar. Você pode parametrizar uma consulta para que seja fácil executá-la em conjuntos de dados de produção e teste.
Por outro lado, parametrizar manualmente consultas SQL com f-strings do Python é uma alternativa ruim. Considere as seguintes desvantagens:
Vamos ver como parametrizar consultas com marcadores de parâmetro, que protegem seu código contra vulnerabilidades de injeção de SQL e suportam a conversão automática de tipos de instâncias PySpark comuns em formato de string.
Suponha que você tenha a seguinte tabela de dados chamada h20_1e9 com nove colunas:
Você gostaria de parametrizar a seguinte consulta SQL:
Você gostaria de facilitar a execução desta consulta com diferentes valores de id1. Veja como parametrizar e executar a consulta com diferentes valores de id1.
Agora execute a consulta novamente com outro argumento:
O formatador de strings PySpark também permite executar consultas SQL diretamente em um DataFrame sem definir explicitamente visualizações temporárias.
Suponha que você tenha o seguinte DataFrame chamado person_df:
Veja como consultar o DataFrame com SQL.
Executar consultas em um DataFrame usando sintaxe SQL sem ter que registrar manualmente uma visualização temporária é muito bom!
Vamos agora ver como parametrizar consultas com argumentos em marcadores de parâmetro.
Você também pode usar um dicionário de argumentos para formular uma consulta SQL parametrizada com marcadores de parâmetro.
Suponha que você tenha a seguinte visualização chamada some_purchases:
Veja como fazer uma consulta parametrizada com marcadores de parâmetro nomeados para calcular o valor total gasto em um determinado item.
Calcule o valor total gasto em meias.
Você também pode parametrizar consultas com marcadores de parâmetro não nomeados; veja aqui para mais informações.
O Apache Spark sanitiza os marcadores de parâmetros, então essa abordagem de parametrização também protege você contra ataques de injeção de SQL.
Aqui está uma descrição de alto nível de como o Spark sanitiza consultas parametrizadas nomeadas:
Como mencionado anteriormente, existem dois tipos de consultas parametrizadas suportadas no PySpark:
A sintaxe {} faz uma substituição de string na consulta SQL no lado do cliente para facilitar o uso e melhorar a programabilidade. No entanto, ela não protege contra ataques de injeção de SQL, pois o texto da consulta é substituído antes de ser enviado ao servidor Spark.
A parametrização usa o argumento args da API sql() e passa o texto SQL e os parâmetros separadamente para o servidor. O texto SQL é analisado com os placeholders de parâmetro, substituindo os valores dos parâmetros especificados em args na árvore de consulta analisada.
Existem dois tipos de consultas parametrizadas do lado do servidor: marcadores de parâmetro nomeados e marcadores de parâmetro não nomeados. Marcadores de parâmetro nomeados usam a sintaxe :<nome_param> para placeholders. Veja a documentação para mais informações sobre como usar marcadores de parâmetro não nomeados.
Você também pode usar interpolação de strings Python regular para parametrizar consultas, mas não é tão conveniente.
Veja como teríamos que parametrizar nossa consulta anterior com f-strings do Python:
Isso não é tão bom pelos seguintes motivos:
Em resumo, as capacidades de parametrização de consulta integradas são mais seguras e eficazes do que a interpolação de strings.
As consultas parametrizadas do PySpark oferecem novas funcionalidades para escrever código limpo com a sintaxe SQL familiar. Elas são convenientes quando você deseja consultar um Spark DataFrame com SQL. Permitem usar tipos de dados Python comuns, como valores de ponto flutuante, strings, datas e datetimes, que são automaticamente convertidos para valores SQL internamente. Dessa forma, você pode aproveitar os idiomas Python comuns e escrever um código elegante.
Comece a usar as consultas parametrizadas do PySpark hoje mesmo e aproveite imediatamente os benefícios de uma base de código de maior qualidade.
Este recurso é oficialmente suportado a partir do DBR 15.2.
(Esta publicação no blog foi traduzida utilizando ferramentas baseadas em inteligência artificial) Publicação original
