Ir al contenido principal

Consultas parametrizadas con PySpark

Parameterized queries with PySpark

Publicado: 3 de enero de 2024

Código abierto7 min de lectura

PySpark siempre ha proporcionado excelentes API de SQL y Python para consultar datos. A partir de Databricks Runtime 15.2 y Apache Spark 4.0, las consultas parametrizadas admiten formas seguras y expresivas de consultar datos con SQL utilizando paradigmas de programación Pythonic.

Esta publicación explica cómo realizar consultas parametrizadas con PySpark y cuándo este es un buen patrón de diseño para su código.

Los parámetros son útiles para hacer que su código Spark sea más fácil de reutilizar y probar. También fomentan buenas prácticas de codificación. Esta publicación demostrará las dos formas diferentes de parametrizar consultas PySpark:

  1. Formato de cadena personalizado de PySpark (custom string formatting)
  2. Marcadores de parámetros

Veamos cómo usar ambos tipos de consultas parametrizadas PySpark y exploremos por qué la funcionalidad integrada es mejor que otras alternativas.

Beneficios de las consultas parametrizadas

Las consultas parametrizadas fomentan el patrón "no te repitas" (DRY), facilitan las pruebas unitarias y hacen que el SQL sea más fácil de reutilizar. También previenen ataques de inyección SQL, que pueden representar vulnerabilidades de seguridad.

Puede ser tentador copiar y pegar grandes fragmentos de SQL al escribir consultas similares. Las consultas parametrizadas fomentan la abstracción de patrones y la escritura de código con el patrón DRY.

Las consultas parametrizadas también son más fáciles de probar. Puede parametrizar una consulta para que sea fácil de ejecutar en conjuntos de datos de producción y de prueba.

Por otro lado, parametrizar manualmente las consultas SQL con f-strings de Python es una alternativa deficiente. Considere las siguientes desventajas:

  1. Las f-strings de Python no protegen contra ataques de inyección SQL.
  2. Las f-strings de Python no entienden objetos nativos de Python como DataFrames, columnas y caracteres especiales.

Veamos cómo parametrizar consultas con marcadores de parámetros, que protegen su código contra vulnerabilidades de inyección SQL y admiten la conversión automática de tipos de instancias comunes de PySpark en formato de cadena.

Consultas parametrizadas con formato de cadena personalizado de PySpark

Suponga que tiene la siguiente tabla de datos llamada h20_1e9 con nueve columnas:

Le gustaría parametrizar la siguiente consulta SQL:

Le gustaría que fuera fácil ejecutar esta consulta con diferentes valores de id1. Aquí se explica cómo parametrizar y ejecutar la consulta con diferentes valores de id1.

Ahora vuelva a ejecutar la consulta con otro argumento:

El formateador de cadenas PySpark también le permite ejecutar consultas SQL directamente en un DataFrame sin definir explícitamente vistas temporales.

Suponga que tiene el siguiente DataFrame llamado person_df:

Aquí se explica cómo consultar el DataFrame con SQL.

¡Ejecutar consultas en un DataFrame usando sintaxis SQL sin tener que registrar manualmente una vista temporal es muy bueno!

Ahora veamos cómo parametrizar consultas con argumentos en marcadores de parámetros.

Consultas parametrizadas con marcadores de parámetros

También puede usar un diccionario de argumentos para formular una consulta SQL parametrizada con marcadores de parámetros.

Suponga que tiene la siguiente vista llamada some_purchases:

Aquí se explica cómo realizar una consulta parametrizada con marcadores de parámetros con nombre para calcular el monto total gastado en un artículo determinado.

Calcule el monto total gastado en calcetines.

También puede parametrizar consultas con marcadores de parámetros sin nombre; consulte aquí para obtener más información.

Apache Spark sanitiza los marcadores de parámetros, por lo que este enfoque de parametrización también lo protege de ataques de inyección SQL.

LIBRO ELECTRÓNICO

Introducción a ETL

Cómo PySpark sanitiza las consultas parametrizadas

Aquí hay una descripción general de cómo Spark sanitiza las consultas SQL parametrizadas con nombre:

  • La consulta SQL llega con una lista opcional de parámetros clave/valor.
  • Apache Spark analiza la consulta SQL y reemplaza las referencias de parámetros con nodos de árbol de análisis correspondientes.
  • Durante el análisis, se ejecuta una regla de Catalyst para reemplazar estas referencias con sus valores de parámetro proporcionados de los parámetros.
  • Este enfoque protege contra ataques de inyección SQL porque solo admite valores literales. La interpolación de cadenas regular aplica la sustitución en la cadena SQL; esta estrategia puede ser vulnerable a ataques si la cadena contiene sintaxis SQL distinta de los valores literales previstos.

Como se mencionó anteriormente, hay dos tipos de consultas parametrizadas admitidas en PySpark:

  • Parametrización del lado del cliente usando la sintaxis {} basada en PEP 3101 (nos hemos referido a esto como formato de cadena personalizado).
  • Parametrización del lado del servidor usando marcadores de parámetros con nombre o marcadores de parámetros sin nombre.

La sintaxis {} realiza una sustitución de cadena en la consulta SQL en el lado del cliente para facilitar su uso y mejorar la programabilidad. Sin embargo, no protege contra ataques de inyección SQL, ya que el texto de la consulta se sustituye antes de enviarse al servidor Spark.

La parametrización utiliza el argumento args de la API sql() y pasa el texto SQL y los parámetros por separado al servidor. El texto SQL se analiza con los marcadores de parámetros, sustituyendo los valores de los parámetros especificados en args en el árbol de consulta analizado.

Hay dos variantes de consultas parametrizadas del lado del servidor: marcadores de parámetros con nombre y marcadores de parámetros sin nombre. Los marcadores de parámetros con nombre utilizan la sintaxis :<nombre_param> para los marcadores de posición. Consulte la documentación para obtener más información sobre cómo usar marcadores de parámetros sin nombre.

Consultas parametrizadas frente a interpolación de cadenas

También puede usar la interpolación de cadenas de Python normal para parametrizar consultas, pero no es tan conveniente.

Así es como tendríamos que parametrizar nuestra consulta anterior con f-strings de Python:

Esto no es tan bueno por las siguientes razones:

  • Requiere la creación de una vista temporal.
  • Necesitamos representar la fecha como una cadena, no como una fecha de Python.
  • Necesitamos envolver la fecha entre comillas simples en la consulta para formatear correctamente la cadena SQL.
  • Esto no protege contra ataques de inyección SQL.

En resumen, las capacidades integradas de parametrización de consultas son más seguras y efectivas que la interpolación de cadenas.

Conclusión

Las consultas parametrizadas de PySpark te brindan nuevas capacidades para escribir código limpio con la sintaxis familiar de SQL. Son convenientes cuando deseas consultar un Spark DataFrame con SQL. Te permiten usar tipos de datos comunes de Python como valores de punto flotante, cadenas, fechas y horas, que se convierten automáticamente en valores SQL internamente. De esta manera, ahora puedes aprovechar los modismos comunes de Python y escribir código elegante.

Comienza a aprovechar las consultas parametrizadas de PySpark hoy mismo y disfrutarás inmediatamente de los beneficios de una base de código de mayor calidad.

Esta función está oficialmente soportada a partir de DBR 15.2.

(Esta entrada del blog ha sido traducida utilizando herramientas basadas en inteligencia artificial) Publicación original

No te pierdas ninguna publicación de Databricks.

Suscríbete a nuestro blog y recibe las últimas publicaciones en tu bandeja de entrada.