Tutorial: Implementación del patrón de captura de Data Lake para actualizar una tabla de Databricks Delta

En este tutorial se muestra cómo controlar eventos en una cuenta de almacenamiento que tiene un espacio de nombres jerárquico.

Creará una pequeña solución que permitirá a un usuario rellenar una tabla de Databricks Delta al cargar un archivo de valores separados por comas (CSV) que describe un pedido de ventas. Esta solución se creará conectando una suscripción a Event Grid, una función de Azure y un trabajo en Azure Databricks.

En este tutorial, aprenderá lo siguiente:

  • Creará una suscripción a Event Grid que llama a una función de Azure.
  • Creará una función de Azure que recibe una notificación de un evento y, a continuación, ejecuta el trabajo en Azure Databricks.
  • Creará un trabajo de Databricks que inserta un pedido de cliente en una tabla de Databricks Delta que se encuentra en la cuenta de almacenamiento.

Crearemos esta solución en orden inverso, empezando por el área de trabajo de Azure Databricks.

Prerrequisitos

Creación de un pedido de ventas

En primer lugar, cree un archivo CSV que describa un pedido de ventas y, a continuación, cargue ese archivo en la cuenta de almacenamiento. Más adelante, usará los datos de este archivo para rellenar la primera fila de la tabla de Databricks Delta.

  1. Vaya a la nueva cuenta de almacenamiento en Azure Portal.

  2. Seleccione Explorador de almacenamiento->Contenedores de blobs->Agregar contenedor y cree un nuevo contenedor denominado Datos.

    Captura de pantalla de la creación de una carpeta en el explorador de almacenamiento.

  3. En el contenedor data, cree un directorio denominado input.

  4. En un editor de texto, pegue el texto siguiente.

    InvoiceNo,StockCode,Description,Quantity,InvoiceDate,UnitPrice,CustomerID,Country
    536365,85123A,WHITE HANGING HEART T-LIGHT HOLDER,6,12/1/2010 8:26,2.55,17850,United Kingdom
    
  5. Guarde este archivo en el equipo local y asígnele el nombre data.csv.

  6. En el explorador de almacenamiento, cargue este archivo en la carpeta input.

Creación de un trabajo en Azure Databricks

En esta sección, realizará estas tareas:

  • Crear un área de trabajo de Azure Databricks.
  • Cree un cuaderno.
  • Crear y rellenar una tabla de Databricks Delta.
  • Agregar código que inserta filas en la tabla de Databricks Delta.
  • Crear un trabajo.

Creación de un área de trabajo de Azure Databricks

En esta sección, creará un área de trabajo de Azure Databricks mediante Azure Portal.

  1. Crear un área de trabajo de Azure Databricks. Asigne a esa área de trabajo el nombre contoso-orders. Consulte Creación de un área de trabajo de Azure Databricks.

  2. Crear un clúster. Asigne el nombre customer-order-cluster al clúster. Consulte Creación de un clúster.

  3. Cree un cuaderno. Asigne al cuaderno el nombre configure-customer-table y elija Python como lenguaje predeterminado del mismo. Consulte Creación de un cuaderno.

Creación y relleno de una tabla de Databricks Delta

  1. En el cuaderno que ha creado, copie y pegue el siguiente bloque de código en la primera celda, pero no ejecute el código aún.

    Reemplace los valores de marcador de posición appId, password y tenant por los valores que recopiló al completar los requisitos previos de este tutorial.

    dbutils.widgets.text('source_file', "", "Source File")
    
    spark.conf.set("fs.azure.account.auth.type", "OAuth")
    spark.conf.set("fs.azure.account.oauth.provider.type", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider")
    spark.conf.set("fs.azure.account.oauth2.client.id", "<appId>")
    spark.conf.set("fs.azure.account.oauth2.client.secret", "<password>")
    spark.conf.set("fs.azure.account.oauth2.client.endpoint", "https://login.microsoftonline.com/<tenant>/oauth2/token")
    
    adlsPath = 'abfss://data@contosoorders.dfs.core.windows.net/'
    inputPath = adlsPath + dbutils.widgets.get('source_file')
    customerTablePath = adlsPath + 'delta-tables/customers'
    

    Este código crea un widget denominado source_file. Más adelante, creará una función de Azure que llama a este código y pasa una ruta de acceso de archivo a ese widget. Este código también autentica la entidad de servicio con la cuenta de almacenamiento y crea algunas variables que usará en otras celdas.

    Nota:

    En una configuración de producción, considere la posibilidad de almacenar su clave de autenticación en Azure Databricks. A continuación, agregue una clave de búsqueda a su bloque de código en lugar de la clave de autenticación.

    Por ejemplo, en lugar de usar esta línea de código: spark.conf.set("fs.azure.account.oauth2.client.secret", "<password>"), debería usar la siguiente: spark.conf.set("fs.azure.account.oauth2.client.secret", dbutils.secrets.get(scope = "<scope-name>", key = "<key-name-for-service-credential>")).

    Una vez completado este tutorial, consulte el artículo Azure Data Lake Storage Gen2 en el sitio Web de Azure Databricks para ver ejemplos de este enfoque.

  2. Presione las teclas MAYÚS + ENTRAR para ejecutar el código de este bloque.

  3. Copie y pegue el siguiente bloque de código en una celda diferente y, a continuación, presione las teclas MAYÚS + ENTRAR para ejecutar el código de este bloque.

    from pyspark.sql.types import StructType, StructField, DoubleType, IntegerType, StringType
    
    inputSchema = StructType([
    StructField("InvoiceNo", IntegerType(), True),
    StructField("StockCode", StringType(), True),
    StructField("Description", StringType(), True),
    StructField("Quantity", IntegerType(), True),
    StructField("InvoiceDate", StringType(), True),
    StructField("UnitPrice", DoubleType(), True),
    StructField("CustomerID", IntegerType(), True),
    StructField("Country", StringType(), True)
    ])
    
    rawDataDF = (spark.read
     .option("header", "true")
     .schema(inputSchema)
     .csv(adlsPath + 'input')
    )
    
    (rawDataDF.write
      .mode("overwrite")
      .format("delta")
      .saveAsTable("customer_data", path=customerTablePath))
    

    Este código crea la tabla de Databricks Delta en la cuenta de almacenamiento y, a continuación, carga algunos datos iniciales del archivo CSV que cargó anteriormente.

  4. Después de que este bloque de código se ejecute correctamente, quítelo del cuaderno.

Agregar código que inserta filas en la tabla de Databricks Delta

  1. Copie y pegue el siguiente bloque de código en otra celda, pero no ejecute la celda.

    upsertDataDF = (spark
      .read
      .option("header", "true")
      .csv(inputPath)
    )
    upsertDataDF.createOrReplaceTempView("customer_data_to_upsert")
    

    Este código inserta datos en una vista de tabla temporal con datos de un archivo CSV. La ruta de acceso a ese archivo CSV procede del widget de entrada que creó en un paso anterior.

  2. Copie y pegue el siguiente bloque de código en una celda distinta. Este código combina el contenido de la vista de tabla temporal con la tabla de Databricks Delta.

    %sql
    MERGE INTO customer_data cd
    USING customer_data_to_upsert cu
    ON cd.CustomerID = cu.CustomerID
    WHEN MATCHED THEN
      UPDATE SET
        cd.StockCode = cu.StockCode,
        cd.Description = cu.Description,
        cd.InvoiceNo = cu.InvoiceNo,
        cd.Quantity = cu.Quantity,
        cd.InvoiceDate = cu.InvoiceDate,
        cd.UnitPrice = cu.UnitPrice,
        cd.Country = cu.Country
    WHEN NOT MATCHED
      THEN INSERT (InvoiceNo, StockCode, Description, Quantity, InvoiceDate, UnitPrice, CustomerID, Country)
      VALUES (
        cu.InvoiceNo,
        cu.StockCode,
        cu.Description,
        cu.Quantity,
        cu.InvoiceDate,
        cu.UnitPrice,
        cu.CustomerID,
        cu.Country)
    

Creación de un trabajo

Cree un trabajo que ejecute el cuaderno que creó anteriormente. Más adelante, creará una función de Azure que ejecuta este trabajo cuando se produce un evento.

  1. Seleccione Nuevo->Trabajo.

  2. Asigne un nombre al trabajo, elija el cuaderno que creó y el clúster. A continuación, seleccione Crear para crear el trabajo.

Creación de una Función de Azure

Cree una función de Azure que ejecute el trabajo.

  1. En el área de trabajo de Azure Databricks, haga clic en el nombre de usuario en la barra superior y seleccione Configuración de usuario en la lista desplegable.

  2. Seleccione Generar nuevo token en la pestaña Tokens de acceso.

  3. Copie el token que se muestra y haga clic en Listo.

  4. En la esquina superior del área de trabajo de Databricks, elija el icono de personas y, a continuación, seleccione Configuración de usuario.

    Administrar cuenta

  5. Seleccione el botón Generar nuevo token y, después, el botón Generar.

    Asegúrese de copiar el token en un lugar seguro. La función de Azure necesita este token para autenticarse con Databricks, para poder ejecutar el trabajo.

  6. En el menú de Azure Portal o en la página Principal, seleccione Crear un recurso.

  7. En la página Nuevo, seleccione Compute>Function App.

  8. En la pestaña Aspectos básicos de la página Crear aplicación de funciones, elija un grupo de recursos y, a continuación, cambie o compruebe la siguiente configuración:

    Configuración Valor
    Nombre de la aplicación de funciones contosoorder
    Pila en tiempo de ejecución .NET
    Publicar Código
    Sistema operativo Windows
    Tipo de plan Consumo (sin servidor)
  9. Seleccione Revisar y crear y, luego, Crear.

    Cuando se complete la implementación, seleccione Ir al recurso para abrir la página Información general de la aplicación de funciones.

  10. En el grupo Configuración, seleccione Configuración.

  11. En la página Configuración de la aplicación, seleccione el botón Nueva configuración de la aplicación para agregar cada opción de configuración.

    Add configuration setting

    Agregue la configuración siguiente:

    Nombre del valor Value
    DBX_INSTANCE La región del área de trabajo de Databricks. Por ejemplo: westus2.azuredatabricks.net
    DBX_PAT El token de acceso personal que generó anteriormente.
    DBX_JOB_ID El identificador del trabajo en ejecución.
  12. Seleccione Guardar para confirmar esta configuración.

  13. En el grupo Funciones, seleccione Funciones y Crear.

  14. Seleccione Azure Event Grid Trigger (Desencadenador de Azure Event Grid).

    Instale la extensión Microsoft.Azure.WebJobs.Extensions.EventGrid si se le solicita. Si tiene que instalarla, tendrá que volver a seleccionar Azure Event Grid Trigger (Desencadenador de Azure Event Grid) para crear la función.

    Aparecerá el panel Nueva función.

  15. En el panel Nueva función, asigne a la función el nombre UpsertOrder y seleccione el botón Crear.

  16. Reemplace el contenido del archivo de código por este código y seleccione el botón Guardar:

      #r "Azure.Messaging.EventGrid"
      #r "System.Memory.Data"
      #r "Newtonsoft.Json"
      #r "System.Text.Json"
      using Azure.Messaging.EventGrid;
      using Azure.Messaging.EventGrid.SystemEvents;
      using Newtonsoft.Json;
      using Newtonsoft.Json.Linq;
    
      private static HttpClient httpClient = new HttpClient();
    
      public static async Task Run(EventGridEvent eventGridEvent, ILogger log)
      {
         log.LogInformation("Event Subject: " + eventGridEvent.Subject);
         log.LogInformation("Event Topic: " + eventGridEvent.Topic);
         log.LogInformation("Event Type: " + eventGridEvent.EventType);
         log.LogInformation(eventGridEvent.Data.ToString());
    
         if (eventGridEvent.EventType == "Microsoft.Storage.BlobCreated" || eventGridEvent.EventType == "Microsoft.Storage.FileRenamed") {
            StorageBlobCreatedEventData fileData = eventGridEvent.Data.ToObjectFromJson<StorageBlobCreatedEventData>();
            if (fileData.Api == "FlushWithClose") {
                  log.LogInformation("Triggering Databricks Job for file: " + fileData.Url);
                  var fileUrl = new Uri(fileData.Url);
                  var httpRequestMessage = new HttpRequestMessage {
                     Method = HttpMethod.Post,
                     RequestUri = new Uri(String.Format("https://{0}/api/2.0/jobs/run-now", System.Environment.GetEnvironmentVariable("DBX_INSTANCE", EnvironmentVariableTarget.Process))),
                     Headers = { 
                        { System.Net.HttpRequestHeader.Authorization.ToString(), "Bearer " + System.Environment.GetEnvironmentVariable("DBX_PAT", EnvironmentVariableTarget.Process)},
                        { System.Net.HttpRequestHeader.ContentType.ToString(), "application/json" }
                     },
                     Content = new StringContent(JsonConvert.SerializeObject(new {
                        job_id = System.Environment.GetEnvironmentVariable("DBX_JOB_ID", EnvironmentVariableTarget.Process),
                        notebook_params = new {
                              source_file = String.Join("", fileUrl.Segments.Skip(2))
                        }
                     }))
                  };
                  var response = await httpClient.SendAsync(httpRequestMessage);
                  response.EnsureSuccessStatusCode();
            }
         }
      }
    

Este código analiza la información sobre el evento de almacenamiento que se ha generado y, a continuación, crea un mensaje de solicitud con la dirección URL del archivo que desencadenó el evento. Como parte del mensaje, la función pasa un valor al widget source_file que creó anteriormente. El código de la función envía el mensaje al trabajo de Databricks y usa el token que obtuvo anteriormente como autenticación.

Creación de una suscripción de Event Grid

En esta sección, creará una suscripción a Event Grid que llama a la función de Azure cuando los archivos se cargan en la cuenta de almacenamiento.

  1. Seleccione Integración y, en la página Integración, seleccione Desencadenador de Event Grid.

  2. En el panel Editar desencadenador, asigne al evento el nombre eventGridEvent y, a continuación, seleccione Crear suscripción de eventos.

    Nota

    El nombre eventGridEvent coincide con el parámetro denominado que se pasa a la función de Azure.

  3. En la pestaña Aspectos básicos de la página Crear suscripción de eventos, cambie o compruebe la siguiente configuración:

    Configuración Valor
    Nombre contoso-order-event-subscription
    Tipo de tema Cuenta de almacenamiento
    Recurso de origen contosoorders
    Nombre del tema del sistema <create any name>
    Filtro para tipos de evento Blob creado y Blob eliminado
  4. Seleccione el botón Crear.

Comprobación de la suscripción a Event Grid

  1. Cree un archivo denominado customer-order.csv, pegue la siguiente información en ese archivo y guárdelo en el equipo local.

    InvoiceNo,StockCode,Description,Quantity,InvoiceDate,UnitPrice,CustomerID,Country
    536371,99999,EverGlow Single,228,1/1/2018 9:01,33.85,20993,Sierra Leone
    
  2. En el Explorador de Storage, cargue este archivo en la carpeta input de su cuenta de almacenamiento.

    Al cargar un archivo, se genera el evento Microsoft.Storage.BlobCreated. Event Grid notifica a todos los suscriptores de ese evento. En nuestro caso, la función de Azure es el único suscriptor. La función de Azure analiza los parámetros del evento para determinar qué evento se ha producido. A continuación, pasa la dirección URL del archivo al trabajo de Databricks. El trabajo de Databricks lee el archivo y agrega una fila a la tabla de Databricks Delta que se encuentra en su cuenta de almacenamiento.

  3. Para comprobar si el trabajo se realizó correctamente, consulte las ejecuciones del trabajo. Verá un estado de finalización. Para obtener más información sobre cómo ver las ejecuciones de un trabajo, consulte Visualización de ejecuciones de un trabajo.

  4. En una nueva celda del libro, ejecute esta consulta para ver la tabla Delta actualizada.

    %sql select * from customer_data
    

    La tabla devuelta muestra el registro más reciente.

    Latest record appears in table

  5. Para actualizar este registro, cree un archivo denominado customer-order-update.csv, pegue la siguiente información en ese archivo y guárdelo en el equipo local.

    InvoiceNo,StockCode,Description,Quantity,InvoiceDate,UnitPrice,CustomerID,Country
    536371,99999,EverGlow Single,22,1/1/2018 9:01,33.85,20993,Sierra Leone
    

    Este archivo CSV es casi idéntico al anterior, salvo que la cantidad del pedido se cambia de 228 a 22.

  6. En el Explorador de Storage, cargue este archivo en la carpeta input de su cuenta de almacenamiento.

  7. Ejecute la consulta select de nuevo para ver la tabla delta actualizada.

    %sql select * from customer_data
    

    La tabla devuelta muestra el registro actualizado.

    Updated record appears in table

Limpieza de recursos

Cuando ya no los necesite, elimine el grupo de recursos y todos los recursos relacionados. Para ello, seleccione el grupo de recursos de la cuenta de almacenamiento y seleccione Eliminar.

Pasos siguientes