viernes, 31 de agosto de 2012

Qualify, Join y Asociatividad

No es ninguna novedad que aterrizar al "mundo de la asociatividad" después de años de bases de datos relacionales puede ser complicado, en particular, cuando tenemos varias tablas con campos de nombres muy genéricos, como son: "DESCRIPCIÓN", "IMPORTE", "CANTIDAD", etc. 
Si bien lo usual es renombrar estos campos "conflictivos", es bastante tedioso hacerlo cuando la cantidad de campos es considerable. La solución rápida y conocida para este tipo de casos es aplicar la función QUALIFY, si aún no la utilizaron activa entre JOINs les adelanto que puede ser algo engorroso.

Para el caso particular con el que voy a trabajar, tengo 2 pares de tablas iguales (ZC y JER), donde cada par de tablas corresponde a una estructura de balance diferente (ACON y AJUS). Cada una de estas 4 tablas las tengo en 4 .QVDs distintos generados en la primer etapa de STG, que se relacionan a través de la tabla de hechos (GLT0). 

Usando QUALIFY  y UNQUALIFY sin complicarse demasiado el modelo nos quedaría:

El código para AJUS:

EL MODELO:


Ahora bien, dejando a un lado las razones técnicas o ideológicas que me motivaron, mi intención es que los campos con igual nombre se diferencien solo por el tipo de estructura de balance y no por el nombre de la tabla, lo que me permitiría trabajar con los campos con mas "homogeneidad" por así decirlo.
Si intentara etiquetar a dos tablas con el mismo nombre, digamos "AUX", teniendo el QUALIFY activo, los nombres de los campos de la primer tabla quedarían AUX.nombreCampomientras que en la segunda tabla quedarían AUX-1.nombreCampo. Pero renombrar una tabla después de cargarla no modifica los nombres de los campos de la misma, de modo que con pocas modificaciones de codigo puedo llegar a mi objetivo.


El código para AJUS:

EL MODELO:

Perfecto! Antes de seguir quiero comentar muy por encima algo sobre los modelos de datos asociativos. Como sabrán, QlikView levanta todo a memoria y una vez allí lo trabaja con un modelo asociativo del que, al momento, no hay detalles técnicos publicados por cuestiones de patente. Algunas cosas que si se saben sobre la asociatividad de QV y son de suma importancia son:
  • Las tablas con los mismos nombres de campos se concatenan automáticamente
  • Tablas que comparten nombres de algunos campos se ASOCIAN automáticamente.  La asociación de la que hablo tiene la misma finalidad que un join, pero con el modelo de datos asociativo. Sobre esto QlikTech indica:
En muchos casos tales joins darán como resultado tablas muy grandes. Una de las principales características de QlikView es la posibilidad de hacer asociaciones entre tablas en lugar de unirlas (join), lo cual reduce el uso de memoria, incrementa la velocidad de proceso y ofrece gran flexibilidad. Los joins explícitos deben ser evitados en los scripts QlikView. La funcionalidad keep fue designada para reducir el número de casos donde necesita usar joins explícitos. 
Teniendo en cuenta esto, no haría falta modificar nada mas en nuestro modelo. 
Sin embargo, ahora me gustaría generar nuevos .QVDs con los nuevos nombres de campos y filtrando un poco. Sabiendo que la relación que tengo entre los campos ERGSL y CUENTA es de uno a uno voy procurar un solo QVD por estructura de balance quedando uno para ACON y otro para AJUS en lugar de 2 para cada uno.

El código para AJUS:

EL MODELO:



Adjunto un Paper en ingles sobre Modelo de Dato Asociativo: Associative Model Data

miércoles, 15 de agosto de 2012

Evaluación Técnica

Una pequeña evaluación para Desarrolladores

  1. Como eliminaría una clave sintética?
  2. Que es la referencia circular y como la eliminaría?
  3. Como intentaría reducir la memoria usada por un documento?
  4.  Diferencia entre LET y SET?
  5. Para qué sirve la sentencia INPUTFIELD?
  6. Codifique 3 ejemplos de set analisys (análisis de conjuntos) y explique cada uno.
  7. Cuál es el resultado del siguiente código:


  1. Usó alguna vez una macros en sus aplicaciones? Si lo hizo, cual uso?
  2. Cuáles son los pasos para generar e imprimir un informe en formato PDF?
  3. Codificar la siguiente línea utilizando la sentencia LOAD.
SELECT * FROM TABLE WHERE CODE IN ('a', 'b', 'f');

  1. Enumere los distintos tipos de seguridad que ofrece QlikView. Si implemento alguno, descríbalo.
  2. Se desea que un botón aplique un filtro sobre el campo CUENTA,  de modo que selecciones las cuentas que empiezan con 22 y 23. Que acción utilizaría y con que código?

  1. Cuál de las siguientes opciones es más eficiente en una expresión de gráfico?

OPCIÓN 1
OPCIÓN 2
Hacer un count(OrderID) siendo:
LOAD
             …,
OrderID,
FROM Orders;

Hacer un sum(OrderRecordCounter) siendo:
LOAD
             …,
OrderID,
1 AS OrderRecordCounter,
FROM Orders;


martes, 14 de agosto de 2012

Control de Cargas

Para quienes, como a mi, su primer encuentro con QlikView fue alguien acercándole un manual de Desarrollador, otro de Diseñador y una fecha de entrega para un proyecto, hay muchas cosas que bien pueden considerarse básicas y que no sabemos.
Una de esas cosas tan fundamentales es como controlar las recargas y que hacer en caso de cancelaciones, por lo que intentare arrojar un poco de luz al respecto.

Antes que nada debemos tener presente algunos conceptos previos.

▄ El esquema gráfico de casi cualquier proyecto en QV se divide en tres etapas generales:

DATA: Extracciones puras de las distintas fuentes.
STG: Tratamiento de los datos extraídos. Esta etapa se puede dividir a su vez en varias etapas de STG.
APPS: La etapa de aplicaciones levanta la información tratada o pura (si no se trato) y los presenta en los diferentes tableros.

▄ En la consola de QV (Publisher, QMEC o como quieran llamarlo) las encargadas de recargar los distintos .QVW son las "tareas de recarga". Las mismas pueden ejecutarse planificadas por calendario, eventos externos o eventos de otras tareas (Finalización satisfactoria o fallida). De interés para el control de cargas, también tienen un TimeOut y una Cantidad de reintentos que establece cuantas veces intentará recargar en caso de fallar.

▄ Finalmente debemos saber el lugar donde se guarda el log de cada tarea de recarga que ejecuta el QDS (QlikView Distribution Service). Esto lo verificamos desde la consola como se muestra en la siguiente imagen, que si bien no es el lugar exacto donde se graban nos deja muy cerca.


Bien, ahora si empezamos con el Control de Cargas. 

Ante la llegada de un mail de alerta por cancelación debemos, antes que nada, verificar que el alerta no sea falsa, esto no es lo normal pero puede suceder, al menos hasta la versión 10 RS 3.
En mi caso los mails de cancelaciones llegan asi:
Del mail solo me interesa el nombre del .QVW que cancelo, en este caso "DATA_SAP_LP0_FI_HRP_1000". Buscando ese nombre en la ruta que hallamos antes deberían aparecer los logs de los ultimos 30 días de recargas (la cantidad de días guardados puede variar según configuración). De paso obtenemos la ruta exacta donde se guardan los logs. En mi caso: "D:\Qlikview\Logs\DistributionService\2\Log\"


Accediendo a la carpeta del día de la cancelación nos podemos encontrar con 2 o 3 archivos, según si la tarea de recarga tenga distribución o no (sobre distribución ya habrá otro post). Ahora mismo nos interesan los archivos DocumentLog.txt (log de cada sentencia de script ejecutada, es el mismo log que obtendríamos recargando a mano desde QlikView) y TaskLog.txt (log de la tarea de recarga).

Llegados a este punto estamos en condiciones de preguntarnos ¿Cuando una alerta de cancelación es falsa? Bien, recuerdan que las tareas de recarga tienen una cantidad de reintentos máximos? bueno, por lo menos hasta la versión 10 RS 3, a veces, si el primer intento de recarga falla pero el siguiente (o uno de los siguientes) funciona el Publisher "no lo reconoce" y sigue relanzando la recarga, cuando finalmente se queda sin reintentos o timeout envía el alerta de cancelación sin importar si los datos se extrajeron bien o mal. 
Entonces para detectar si el alerta es falsa o no, debemos revisar el DocumentLog y buscar el texto Execution finished, si por cada vez que aparece ese texto arriba dice que falló ("Execution Failed") entonces el alerta es verdadera, de lo contrario habrá sido una falsa alarma.

Dos ejemplos de lo que intento explicar.
Alerta verdadera:

La recarga falla en cada intento y deja de intentar porque se le acaban la cantidad de reintentos o por timeout.

Alerta Falsa:


Si bien el primer intento falla, podemos ver como la segunda vez que finaliza la ejecución no presenta mensaje de cancelación arriba, al contrario tiene un llamado a la rutina final que recupera un timestamp de fin de ejecución, y aún así se relanza nuevamente la recarga.

Una vez que accedemos a la consola las cancelaciones se visualizan con rojo como se ve en las imagenes, tanto si las cancelaciones fueron verdaderas o falsas debemos abrir el arbol de tareas de recarga hasta llegar a una tarea despues de las canceladas y verificar que se haya ejecutado todo mirando la hora de la ultima ejecución.

Para este caso las alertas fueron verdaderas por lo que relanzo las recargas de todo lo que canceló presionando en el boton  . De haber sido falsas debería mirar en la columna Last Execution, si la fecha es posterior a la cancelación de arriba no hará falta relanzar nada, si es anterior a la misma en lugar de relanzar la recarga de lo que esta en rojo bastaría con relanzar las recargas siguientes ya que no se lanzaron como se esperaba.

 

Teniendo en cuenta las etapas que se presentaron en un principio y ya que las cancelaciones fueron en la etapa DATA corresponde relanzar las recargas de las etapas STG y APPS (una vez hayan terminado las bien DATA), pues no puede asegurarse la fiabilidad ni completitud de los datos con los que se recargaron.



Para mi caso STG se divide en "STG de SAP" y "STG de indicadores y APPS" por lo que relanzo la primera y una vez finalizada relanzo la otra etapa.


Una vez haya terminado de recargar el ultimo QVW estaremos en condiciones de reportar la disponibilidad de los datos al usuario y ser felices. Espero que algo de todo lo dicho pueda servir a quien no haya podido hacer los cursos. 

Saludos