Преобразовать часть ETL, используя Scriptella?

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

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

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

<!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 ответ

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

(Запрос) Необработанные данные -> (Запрос) манипулировать данными -> (Сценарий) записать новые данные.

.. 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>
Другие вопросы по тегам