Saltar al contenido

Actualizar o insertar datos de Clarizen con una cadena de operaciones en Jitterbit Design Studio

Introducción

Este patrón de integración utiliza una cadena de operaciones dentro de Harmony Design Studio para actualizar o insertar datos en tu instancia de Clarizen conectada. Antes de comenzar, ya debes estar familiarizado con cómo funciona Jitterbit, tener configurado un endpoint de Clarizen, y ser capaz de utilizar las operaciones nativas de consulta, creación y actualización dentro del conector de Clarizen de Design Studio.

Resumen

El propósito de una operación de actualizar o insertar es actualizar registros que ya existen e insertar registros que no existen. Aunque la API REST de Clarizen no admite explícitamente operaciones de actualizar o insertar, Jitterbit permite configuraciones simples y flexibles de flujos de trabajo de inserción/actualización.

En este patrón, se utiliza un campo de clave única para determinar la existencia de un registro buscando un registro en Clarizen cuyo campo de clave única tenga el mismo valor. El campo de clave única debe tener un valor diferente para cada registro y ser el mismo en ambos sistemas. Se puede utilizar cualquier campo que ya mantenga estas propiedades, y si ninguno existe en el objeto, se puede crear un campo personalizado en Clarizen para almacenar los IDs de registro del sistema de origen.

El siguiente diagrama muestra el flujo de trabajo generalizado de una operación de actualizar o insertar en Clarizen utilizando este patrón de diseño.

attachment

Específicamente, actualizar o insertar registros en Clarizen requiere mantener pares (clave, valor) de los valores de clave única y hacer coincidir esos con los IDs de registro de Clarizen. Luego, los registros se pueden separar en "crear" o "actualizar" según si su clave única tiene un ID de Clarizen correspondiente en el almacén de claves.

Existen numerosas formas de implementar el almacén de claves y la separación de registros, con diferentes niveles de eficiencia. A continuación se presenta la implementación que seguiremos en este patrón, que sacrifica eficiencia por simplicidad en ciertos lugares. Los números corresponden con los pasos incluidos en la siguiente sección.

attachment

Implementación

Las siguientes secciones describen los pasos principales para implementar este patrón de diseño. Como ejemplo, actualizaremos o insertaremos datos de objeto de Usuario existentes en Clarizen en nuestros datos de objeto de Cliente en Clarizen. Esta es la configuración final:

attachment

Paso 1 - Obtener datos de origen para actualizar o insertar

attachment

Primero, trae los datos que deseas utilizar para la operación de actualizar o insertar utilizando la funcionalidad estándar de Jitterbit. Puedes utilizar una variedad de fuentes de datos.

Para este ejemplo, consultaremos todos los empleados existentes del objeto Usuario dentro de nuestra instancia de Clarizen conectada, y luego utilizaremos estos datos como fuente para nuestra operación de actualizar o insertar. Para el ejemplo, configuramos nuestros datos de origen de la siguiente manera:

  1. Crea una nueva operación de consulta de Clarizen para el objeto Usuario y selecciona todos los campos. La consulta se llama "Query Employees."

  2. Crea una operación a partir de esta consulta (haz clic en el botón Create Operation). La operación se llama "1. Obtain Source Data to be Upserted."

  3. Pasa los datos a través de la transformación sin cambios (haz clic derecho en Response > Pass-Through). También podrías configurar una transformación normal para obtener datos en el formato que desees utilizar.

  4. Establece el destino como almacenamiento temporal, denominado "Employees" (haz doble clic en Target > Create New Target; tipo: "Temporary Storage"; nombre de archivo: "employees").

  5. Copia el destino "Employees" a un origen, también denominado "Employees" (dentro del árbol de la izquierda, haz clic derecho en el destino específico > Copy to New Source). Se utilizará como origen para los datos de upsert en la siguiente operación.

  6. Ejecuta una nueva operación de transformación al tener éxito (haz clic derecho en el fondo de la operación > On Success > Operation > Create New Operation > Transformation). Esta operación se utilizará en el Paso 2, a continuación.

Paso 2 - Agregar claves únicas a un diccionario

attachment

Se utiliza un diccionario en este patrón para mantener los pares (clave única, ID de Clarizen). En esta operación, insertaremos un script antes del origen para inicializar un diccionario global y crear una transformación para asignar el campo de clave única.

  1. Dependiendo de cómo hayas configurado tu origen, ya deberías tener una nueva operación en blanco creada desde el Paso 1. Si no es así, crea una nueva operación de transformación (New Operation > Transformation). La operación se denomina "2. Add Unique Keys to Dictionary."

  2. Especifica el origen de tus datos. El origen debe contener todos los registros a ser upserted. En el ejemplo utilizamos el origen "Employees" creado desde el Paso 1 (haz doble clic en Source y selecciona el origen "Employees" existente).

  3. No se necesita destino, así que elimina el destino de la operación (haz clic derecho en Target > Remove from Graph).

  4. Inserta un script antes del origen (haz clic derecho en Source > Insert Before This > Script) y crea un nuevo script (denominado "Initialize the Dictionary") como sigue:

    <trans>
    $UpsertIdDict = Dict();
    </trans>
    
  5. Crea una nueva transformación cuyas estructuras de origen y destino sean las mismas que tus datos (haz doble clic en Transformation > Create New Transformation). La transformación en el ejemplo se denomina "Map Unique Key Field."

    1. Para el origen, selecciona la misma estructura que tus datos de origen. En el ejemplo nuestro origen es el resultado de una consulta de Clarizen, así que utilizamos "Clarizen Function Response." Para el destino, elegiremos "Text."
    2. Para el origen, sigue las indicaciones del asistente; en el ejemplo selecciona "Query" y la operación de consulta específica utilizada como origen.
    3. Para el destino, crearemos manualmente una nueva estructura que tenga un campo (Available File Format Definitions > Create New > Create Manually; en Define Segment Properties, haz clic en New e ingresa un nombre de campo, por ejemplo "ID"). En el ejemplo el nombre del formato de archivo es "Unique Keys."
    4. En la transformación, itera sobre el campo de clave única asignándolo del lado del origen al lado del destino (en el ejemplo arrastra y suelta el campo User > Entity > "id" de la izquierda al campo "ID" de la derecha).
  6. Modifica la transformación para que se agregue una nueva entrada en el diccionario con el campo de clave única como ID y '0' como valor. Para hacerlo, haz doble clic en tu campo ID del lado del destino e ingresa lo siguiente:

    <trans>
    AddToDict($UpsertIdDict, Quote(<Your_Unique_Key>), 0)
    </trans>
    

    En el ejemplo, \<Your_Unique_Key> se reemplaza con OUTPUT\(User\)Entity.id$ seleccionando el campo de clave única del lado del origen.

    <trans>
    AddToDict($UpsertIdDict, Quote(OUTPUT$User$Entity.id$), 0)
    </trans>
    
  7. Inserta un nuevo script después de la transformación que acabas de crear (haz clic derecho en la transformación > Insert After This > Script) y crea un nuevo script llamado "Update Keystore." Por ahora dejaremos el script en blanco. Se completará más adelante durante el siguiente paso para crear un filtro de modo que solo se consulten los registros de Clarizen cuyas claves únicas coincidan con una en el diccionario.

Paso 3 - Consultar Clarizen para registros con claves únicas coincidentes

attachment

Para rellenar el diccionario con los IDs de Clarizen asociados, en este patrón necesitarás crear una nueva operación de consulta de Clarizen para el objeto al que deseas hacer upsert. Se debe consultar el ID y la clave única, y se debe agregar una variable de proyecto al final para incluir una cláusula WHERE.

  1. Crea una nueva operación de consulta de Clarizen para tu objeto (en el ejemplo, usamos el objeto Customer) con una cadena de consulta en el siguiente formato.

    SELECT <Your_Unique_Key> FROM <Your_Object> Where <Your_Unique_Key> In [ClarizenWhereClause]
    

    En el ejemplo, usaremos un campo personalizado llamado "C_JB_External_Id" en nuestro objeto Customer como nuestra clave única, de la siguiente manera:

    SELECT C_JB_External_Id FROM Customer Where C_JB_External_Id In [ClarizenWhereClause]
    

    Nota

    La [ClarizenWhereClause] es una variable de proyecto que definiremos más adelante en el script "Update Keystore".

  2. Crea una operación a partir de esta consulta (haz clic en el botón Create Operation). La operación se llama "3. Query Clarizen for Records with Matching Unique Keys."

  3. No se necesita un destino, así que elimina el destino de la operación (haz clic derecho en Target > Remove from Graph).

  4. Crea una nueva transformación (haz doble clic en Transformation > Create New Transformation). La transformación en el ejemplo se llama "Match Unique Keys."

    1. En el ejemplo, el origen ya debe estar definido como la respuesta de la consulta del objeto. Para el destino, elegiremos "Text."
    2. Para la estructura de destino, selecciona el mismo formato de archivo creado durante el Paso 2 (en el ejemplo, llamado "Unique Keys").
    3. En la transformación, asigna los campos de ID del lado del origen al lado del destino (en el ejemplo, arrastra y suelta tanto el campo User > Entity > "id" como el campo personalizado "C_JB_External_Id" de la izquierda al campo "ID" de la derecha).
  5. Modifica la transformación para escribir los IDs de Clarizen en los valores del diccionario para las claves únicas correspondientes. Esto establecerá tu clave única igual a tu ID de objeto. Para hacerlo, haz doble clic en tu campo de ID en el lado del destino e ingresa lo siguiente:

    <trans>
    $UpsertIdDict[Quote(OUTPUT$<Your_Object>$Entity.<Your_Unique_Key>$)] = OUTPUT$<Your_Object>$Entity.id$;
    </trans>
    

    Recuerda que puedes hacer doble clic en los campos bajo OUTPUT en el lado derecho para obtener los campos apropiados para tu clave única y objeto. El ejemplo se lee de la siguiente manera:

    <trans>
    $UpsertIdDict[Quote(OUTPUT$Customer$Entity.C_JB_External_Id$)] = OUTPUT$Customer$Entity.id$;
    </trans>
    
  6. A continuación, crea un nuevo script que construya una cláusula IN a partir de las claves del diccionario. Esto se puede crear fuera de la operación (en el árbol de la izquierda, haz clic derecho en Scripts > New Script). El script en el ejemplo se llama "Construct InClause from Dict Keys." Pega lo siguiente en el script:

    <trans>
    ArgumentList(Dictionary, start, end);
    keys = GetKeys(Dictionary);
    
    //keyIter = 0;
    inClause = '';
    if(end > length(keys),
    //use length keys as condition
    while( start <length(keys)-1,
        inClause = inClause + keys[start] + ', ';
        start++;);,
    while( start < end ,
        inClause = inClause + keys[start] + ', ';
        start++;);
    );
    
    inClause + keys[start]
    </trans>
    
  7. Ahora que se ha creado el script de cláusula IN, podemos usarlo dentro del script "Update Keystore" que se creó al final de la segunda operación en el Paso 2. Este script recorre tu diccionario de claves y busca en Clarizen un registro coincidente. Una vez finalizado, ejecutará las operaciones de actualización e inserción que configuraremos en los próximos pasos. Haz doble clic en este script e ingresa lo siguiente, sustituyendo los nombres de tus scripts y operaciones reales donde sea necesario.

    <trans>
    //Update cache
    keys = GetKeys($UpsertIdDict);
    //WriteToOperationLog(keys);
    interval = 999;
    batch = 0;
    
    While(batch*interval < Length(keys),
    $ClarizenWhereClause = '(' + RunScript("<TAG>Scripts/Construct InClause From Dict Keys</TAG>",$UpsertIdDict, batch*interval, (batch + 1)*interval - 1) + ')';
    WriteToOperationLog($ClarizenWhereClause);
    If(!RunOperation("<TAG>Operations/3. Query Clarizen for Records with Matching Unique Keys</TAG>",true),
    RaiseError(GetLastError())
    );
    batch ++;
    );
    
    RunOperation("<TAG>Operations/4. Separate Records to Update; Update Records</TAG>",false);
    RunOperation("<TAG>Operations/5. Separate Records to Create; Insert Records</TAG>",false)
    </trans>
    

    Importante

    La llamada sincrónica RunOperation dentro del bucle While está sujeta a un límite a nivel de agente en las llamadas sincrónicas realizadas dentro de un único bucle While (50 por defecto). Con interval = 999, este bucle alcanza ese límite aproximadamente en 50,000 claves; para las cargas de 100,000 registros descritas en Optimization, el bucle alcanza el límite a mitad de camino y los lotes restantes no se consultan. Consulta la nota bajo RunOperation para saber cómo configurar o anular este límite, o aumenta interval para reducir el número de iteraciones del bucle para conjuntos de claves grandes.

Nota

La última parte de este script conecta las operaciones que se crearán en los Pasos 4 y 5. Es posible que necesites volver a este script al final para actualizar los nombres de las operaciones si es necesario.

Paso 4 - Separar registros para actualizar, luego actualizar registros en Clarizen

attachment

Este paso filtra los registros para una operación de actualización en Clarizen y luego realiza la actualización de registros en la instancia de Clarizen.

  1. Crea una nueva operación de actualización en Clarizen para el objeto que deseas actualizar (en el ejemplo, el objeto Customer).

  2. Especifica la fuente que contiene todos los registros a ser insertados o actualizados. En el ejemplo usamos la fuente "Employees" creada en el Paso 1 (haz doble clic en Source y selecciona la fuente "Employees" existente).

  3. No se necesita un destino, así que elimina el destino de la operación (haz clic derecho en Target > Remove from Graph).

  4. Crea una nueva transformación de solicitud (haz doble clic en Request > Create New Transformation). La transformación en el ejemplo se llama "Separate Records to Update."

    1. Para la fuente, selecciona la misma estructura que tus datos de origen. En el ejemplo nuestra fuente es el resultado de una consulta en Clarizen, así que usamos "Clarizen Function Response." El destino debe definirse como una solicitud a la operación de actualización.

    2. Para la fuente del ejemplo, sigue las indicaciones del asistente, en el ejemplo seleccionando "Query" y la operación de consulta específica utilizada como fuente. Si tienes un tipo de fuente diferente, selecciona las opciones apropiadas.

    3. En la transformación, crea una condición en la carpeta del objeto destino (en el ejemplo haz clic derecho en la carpeta Customer > Add condition). La condición debe devolver verdadero cuando se encuentra el registro en el diccionario, y falso cuando no se encuentra:

      <trans>
      if($UpsertIdDict[Quote(OUTPUT$<Your_Object>$Entity.id$)]!='0',
      WriteToOperationLog('Found in Dict');
      true,
      WriteToOperationLog('Not Found In Dict');
      false)
      </trans>
      

      En el ejemplo, la condición se establece de la siguiente manera:

      <trans>
      if($UpsertIdDict[Quote(OUTPUT$User$Entity.id$)]!='0',
      WriteToOperationLog('Found in Dict');
      true,
      WriteToOperationLog('Not Found In Dict');
      false)
      </trans>
      
    4. Luego, asigna el campo ID recuperándolo del diccionario usando la clave única. Es decir, haz doble clic en el ID en el lado destino e ingresa lo siguiente:

      <trans>
      $UpsertIdDict[Quote(OUTPUT$<Your_Object>$Entity.id$)]
      </trans>
      

      En el ejemplo, esto se establece de la siguiente manera:

      <trans>
      $UpsertIdDict[Quote(OUTPUT$User$Entity.id$)]
      </trans>
      
    5. Continúa asignando los campos ID restantes, así como cualquier otro campo que deba asignarse al actualizar. En el ejemplo, también asignamos el campo User > Entity > "id" al campo Customer > "C_JB_External_Id" (campo personalizado) a la derecha. En el ejemplo, el campo User > Entity > "DisplayName" también se asigna al campo Customer > "Name" a la derecha.

  5. Para la transformación de respuesta restante en la operación, puedes pasar los datos a través de la transformación sin cambios (haz clic derecho en Response > Pass-Through).

  6. Cuando tu operación de actualización esté completa, verifica nuevamente el script "Update Keystore" descrito al final del Paso 3 para asegurarte de que esta operación se incluya para ejecutarse dentro del script.

Paso 5 - Separar registros para crear, luego insertar registros en Clarizen

attachment

Este paso filtra los registros para una operación de creación en Clarizen y luego realiza la inserción de registros en la instancia de Clarizen.

  1. Crea una nueva operación de creación en Clarizen para el objeto en el que deseas insertar datos (en el ejemplo, el objeto Customer).

  2. Especifica la fuente que contiene todos los registros a ser insertados o actualizados. En el ejemplo usamos la fuente "Employees" creada en el Paso 1 (haz doble clic en Source y selecciona la fuente "Employees" existente).

  3. No se necesita un destino, así que elimina el destino de la operación (haz clic derecho en Target > Remove from Graph).

  4. Crea una nueva transformación de solicitud (haz doble clic en Request > Create New Transformation). La transformación en el ejemplo se llama "Separate Records to Create."

    1. Para la fuente, selecciona la misma estructura que tus datos de origen. En el ejemplo, nuestra fuente es el resultado de una consulta de Clarizen, así que usamos "Clarizen Function Response." El destino debe definirse como una solicitud para la operación de creación.

    2. Para la fuente del ejemplo, sigue las indicaciones del asistente; en el ejemplo selecciona "Query" y la operación de consulta específica utilizada como fuente. Si tienes un tipo de fuente diferente, selecciona las opciones apropiadas.

    3. En la transformación, crea una condición en la carpeta del objeto destino (en el ejemplo haz clic derecho en la carpeta Customer > Add condition). La condición debe devolver false cuando se encuentra el registro en el diccionario, y true cuando no se encuentra:

      <trans>
      if($UpsertIdDict[Quote(OUTPUT$<Your_Object>$Entity.id$)]=='0',
      WriteToOperationLog('Not Found in Dict. Creating CZ customer');
      true,
      WriteToOperationLog('Found In Dict. Customer already exists in CZ');
      false)
      </trans>
      

      En el ejemplo, la condición se establece de la siguiente manera:

      <trans>
      if($UpsertIdDict[Quote(OUTPUT$User$Entity.id$)]=='0',
      WriteToOperationLog('Not Found in Dict. Creating CZ customer');
      true,
      WriteToOperationLog('Found In Dict. Customer already exists in CZ');
      false)
      </trans>
      
    4. Continúa mapeando los campos de ID restantes, así como cualquier otro campo que deba mapearse al actualizar. En el ejemplo, también mapeamos el campo User > Entity > "id" a Customer > "C_JB_External_Id" (campo personalizado) a la derecha. En el ejemplo, el campo User > Entity > "DisplayName" también se mapea al campo Customer > "Name" a la derecha.

  5. Para la transformación de respuesta restante en la operación, puedes pasar los datos a través de la transformación sin cambios (haz clic derecho en Response > Pass-Through).

  6. Cuando tu operación de creación esté completa, verifica nuevamente el script "Update Keystore" descrito al final del Paso 3 para asegurarte de que esta operación se incluya para ejecutarse dentro del script.

Optimización

El patrón de diseño presentado anteriormente utiliza un diccionario para mantener claves únicas con sus IDs de Clarizen asociados con el propósito de simplificar.

Esto es suficiente para muchos casos de uso, pero como el diccionario no persiste, Clarizen debe consultarse cada vez para crear el almacén de claves. Esto agregará al menos 1 uso de API adicional por cada registro actualizado o insertado.

Dado que se puede usar una consulta masiva para consultar 100,000 registros por llamada, el costo generalmente es insignificante para cargas de datos grandes. Sin embargo, para aplicaciones en tiempo real de alta frecuencia, esto puede convertirse rápidamente en una adición costosa.

Una alternativa es usar la caché en la nube de Jitterbit para almacenar estos IDs. Hay algunas complejidades adicionales al usar la caché en la nube; como solo permite 250 lecturas/escrituras por segundo, el implementador debe manejar el caso en que la lectura o escritura falle.

Otras alternativas son usar capas de persistencia externa para mantener el almacén de claves, o usar almacenamiento local si se utiliza un agente privado.