2015-03-01 2 views
0

Я использую Scriptella, чтобы узнать, удовлетворит ли она мои потребности. Пока что это отличный инструмент. Я потратил несколько часов на изучение образцов сценариев, поиск в форумах и попытку получить зависание вложенных запросов/скриптов.Преобразование части ETL с использованием Scriptella?

Это пример моего файла ETL, слегка очищенного для краткости. Строки, начинающиеся с #, добавляются, а не являются частью фактического файла ETL. Я пытаюсь вставить/получить идентификаторы, а затем передать их на более поздние блоки скриптов. Самый многообещающий способ сделать это, похоже, использует глобальные переменные, но я получаю null при попытке получить значения. Позже я добавлю код в блоки скриптов, которые анализируют и значительно трансформируют поля, прежде чем добавлять их в БД.

Ошибок не существует. Я просто не получаю идентификаторы ОС и идентификаторы категорий, которые я ожидал бы. Заранее спасибо.

<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd"> 
<etl> 
    <connection id="in" driver="csv" url="mycsvfile.csv"/> 
    <connection id="dest" url="jdbc:mysql://localhost:3306/pvm3" user="user" password="password"/> 
    <connection id="js" driver="script"/> 

    <query connection-id="in"> 
     <!-- all columns are selected, notably: OPERATINGSYSTEM, CATEGORY, QID, TITLE --> 

     <query connection-id="dest"> 
      #Check to see if the OS already exists, and get the ID if it does 
      select max(os_id) as os_id, count(*) as os_cnt from etl_os where os = ?OPERATINGSYSTEM; 

      #If it doesnt exist then add it and get the auto_increment value 
      <script if="os_cnt==0"> 
       insert into etl_os(os) values(?OPERATINGSYSTEM); 

       <query connection-id="dest"> 
        select last_insert_id() as os_id; 

        #Store in global so it can be accessed in later script blocks 
        <script connection-id="js"> 
         etl.globals.put('os_id', os_id); 
        </script> 
       </query> 
      </script> 

      #Same style select/insert as above for category_id (excluded for brevity) 

      #See if KB record exists by qid, if not then add it with the OS ID and category ID we got earlier 
      <query connection-id="dest"> 
       select max(qid) as existing_qid, count(*) as kb_cnt from etl_qids where qid = ?QID 

       <script if="kb_cnt==0"> 
        insert into etl_qids(qid, category_id, os_id) values (?QID, ?{etl.globals.get('category_id')}, ?{etl.globals.get('os_id')}); 
       </script> 
      </query> 

     </query> 

    </query> 
</etl> 

ответ

1

Обнаружено, как это сделать. По сути, просто вложенные запросы для изменения данных перед передачей их скрипту. Ниже приведен быстрый вариант решения. Сначала я не понял, что запросы могут быть сразу вложены, чтобы преобразовать строку, прежде чем передавать ее для обработки. Мое впечатление также заключалось в том, что только скрипты могут манипулировать данными.

(Запрос) Необработанные данные -> (Запрос) обрабатывают данные -> (Script) записывают новые данные.

.. in is a CSV file .. 
.. js is a driver="script" block .. 

<query connection-id="in"> 
    <query connection-id="js"> 
     //transform data as needed here 
     if (BASE_TYPE == '-') BASE_TYPE = '0'; 
     if (SECONDARY_TYPE == '-') SECONDARY_TYPE = '0'; 
     SIZES = SIZES.toLowerCase(); 

     query.next(); //call nested scripts 

     <script connection-id="db"> 
      INSERT IGNORE INTO sizes(size) VALUES (?SIZE); 
      INSERT IGNORE INTO test(base_type,secondary_type) VALUES (?BASE_TYPE, ?SECONDARY_TYPE); 
     </script> 

    </query> 
</query>