Scriptella - динамически именовать CSV-файл

Я хотел бы создать файл csv со значением, которое я получаю во время выполнения сценария etl. Например. Я получаю новое значение из последовательности и хочу добавить его к имени CSV. Звучит просто, но я действительно застрял...

Мой сценарий:

<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
    <description>Scriptella ETL</description>
    <properties>
        <include href="etl.properties"/> <!--Load from external properties file-->
    </properties>
    <!-- Connection declarations -->
    <connection id="mypostgres" driver="$driver" url="$url" user="$user" password="$password" classpath="$classpath"/>
    <connection driver="jexl" id="jexl"/>
    <connection id="log" driver="text"/>

    <query connection-id="mypostgres">
        select nextval('transfer_id_seq') as tid
        <script connection-id="jexl">
            etl.globals['transferID'] = tid;
        </script>
        <script connection-id="log">
            TransferID: ${etl.globals['transferID']}
        </script>
    </query>

    <script connection-id="log">
        TransferID (Outside query): ${etl.globals['transferID']}
    </script>

    <connection id="transfer-csv" driver="csv" url="transfer_${etl.globals['transferID']}.csv">
        null_string=
        quote=
    </connection>

    <script connection-id="transfer-csv">
        col1, col2, col3
    </script>
</etl>

Мой вывод:

C:\scriptella>scriptella
C:\java\jdk1.8\bin\java.exe -cp ;C:\dev\scriptella-1.1\lib\commons-compiler-jdk.jar;C:\dev\scriptella-1.1\lib\commons-compiler.jar;C:\dev\scriptella-1.1\lib\commons-jexl.jar;C:\dev\scriptella-1.
1\lib\commons-logging.jar;C:\dev\scriptella-1.1\lib\janino.jar;C:\dev\scriptella-1.1\lib\scriptella-core.jar;C:\dev\scriptella-1.1\lib\scriptella-drivers.jar;C:\dev\scriptella-1.1\lib\scriptella-tools
.jar scriptella.tools.launcher.EtlLauncher
23.02.2015 17:33:58 <WARNING> XML configuration warning in file:/C:/scriptella/etl.xml(35:7): The content of element type "etl" must match "(description?,properties?,connection*,(script*,
query*)*)".
23.02.2015 17:33:58 <INFO> Execution Progress.Initializing properties: 1%
23.02.2015 17:33:58 <INFO> Execution Progress.Initialized connection id=mypostgres, JdbcConnection{org.postgresql.jdbc4.Jdbc4Connection}, Dialect{PostgreSQL 9.3.2}, properties {}: 2%
23.02.2015 17:33:58 <INFO> Execution Progress.Initialized connection id=jexl, JexlConnection, Dialect{JEXL 2.0}, properties {}: 3%
23.02.2015 17:33:58 <INFO> Execution Progress.Initialized connection id=log, TextConnection, Dialect{Text 1.0}, properties {}: 4%
23.02.2015 17:33:58 <INFO> Execution Progress.Initialized connection id=transfer-csv, CsvConnection, Dialect{CSV 1.0}, properties {null_string=, quote=}: 5%
23.02.2015 17:33:58 <INFO> Execution Progress./etl/query[1] prepared: 6%
23.02.2015 17:33:58 <INFO> Execution Progress./etl/script[1] prepared: 7%
23.02.2015 17:33:58 <INFO> Execution Progress./etl/script[2] prepared: 10%
23.02.2015 17:33:58 <INFO> Registered JMX mbean: scriptella:type=etl,url="file:/C:/scriptella/etl.xml"
TransferID: 171
23.02.2015 17:33:58 <INFO> Execution Progress./etl/query[1] executed: 38%
TransferID (Outside query): 171
23.02.2015 17:33:58 <INFO> Execution Progress./etl/script[1] executed: 66%
23.02.2015 17:33:58 <INFO> Execution Progress./etl/script[2] executed: 95%
23.02.2015 17:33:58 <INFO> Execution Progress.Complete
23.02.2015 17:33:58 <INFO> Execution statistics:
Executed 1 query, 4 scripts, 4 statements
/etl/query[1]: Element successfully executed (1 statement). Working time 11 milliseconds. Avg throughput: 89,63 statements/sec.
/etl/query[1]/script[1]: Element successfully executed. Working time 9 milliseconds.
/etl/query[1]/script[2]: Element successfully executed (1 statement). Working time 4 milliseconds. Avg throughput: 206,37 statements/sec.
/etl/script[1]: Element successfully executed (1 statement). Working time 2 milliseconds. Avg throughput: 432,13 statements/sec.
/etl/script[2]: Element successfully executed (1 statement). Working time 2 milliseconds. Avg throughput: 447,04 statements/sec.
Total working time: 0,26 second
23.02.2015 17:33:58 <INFO> Successfully executed ETL file C:\scriptella\etl.xml

Как вы видите, имя файла csv неверно:

Directory of C:\scriptella

23.02.2015  17:33    <DIR>          .
23.02.2015  17:33    <DIR>          ..
23.02.2015  11:28               282 etl.properties
23.02.2015  17:32             1.239 etl.xml
23.02.2015  17:33               133 transfer_transferID.csv
               3 File(s)          1.654 bytes
               2 Dir(s)     741.036.032 bytes free

person Buka    schedule 23.02.2015    source источник


Ответы (2)


Невозможно иметь элемент динамического соединения, так как Scriptella обрабатывает все соединения при запуске (из вашей 5% строки журнала):

23.02.2015 17:33:58 <INFO> Execution Progress.Initialized connection id=transfer-csv, CsvConnection, Dialect{CSV 1.0}, properties {null_string=, quote=}: 5%

Лучший вариант — использовать драйвер scriptella, который позволит вам вызывать другой etl.xml в качестве подпрограммы (и на самом деле не нужны глобальные переменные):

этл.xml:

<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
    <description>Scriptella ETL</description>
    <properties>
        <include href="etl.properties"/> <!--Load from external properties file-->
    </properties>
    <!-- Connection declarations -->
    <connection id="mypostgres" driver="$driver" url="$url" user="$user" password="$password" classpath="$classpath"/>
    <connection id="log" driver="text"/>
    <connection id="scriptella" driver="scriptella"/>
    <query connection-id="mypostgres">
        select nextval('transfer_id_seq') as tid
        <script connection-id="log">
            TransferID: $tid
        </script>
        <script connection-id="scriptella">
            dynamic.xml
        </script>
    </query>
</etl>

динамический.xml:

<!DOCTYPE etl SYSTEM "http://scriptella.javaforge.com/dtd/etl.dtd">
<etl>
    <connection id="transfer-csv" driver="csv" url="transfer_${tid}.csv">
       null_string=
        quote=
    </connection>
    <script connection-id="transfer-csv">
        col1, col2, col3
    </script>
</etl>

ПРИМЕЧАНИЕ. Синтаксис ${var} обязателен в URL-адресе подключения файла dynamic.xml.

Кроме того, нет никакого способа, чтобы скриптелла добавлялась к файлу csv (он будет усекаться каждый раз), поэтому я думаю, что то, что вы пытаетесь выполнить, может потребовать переосмысления вашего процесса. Часто задаваемые вопросы о Scriptella по работе с данными CSV предлагает использовать текстовые таблицы HSQLDB, которые могут помочь - использование HSQLDB или H2 для подготовки данных, которые вам нужно экспортировать, вероятно, приведет к увеличению производительности и сделает ваш процесс более удобным в долгосрочной перспективе.

person Sean Summers    schedule 24.04.2015
comment
Шон, спасибо за ваш ответ. Очень креативно. Это похоже на хорошее решение. Переосмысление моего процесса... Это привело к тому, что скриптеллу больше не используют, потому что заставить ее работать очень сложно, а также они прекратили ее разработку. Я выбрал Groovy, но подойдет и другой инструмент для написания сценариев. - person Buka; 04.05.2015

В Scriptella 1.2 (я не уверен, что это применимо к более старым версиям Scriptella) вы можете динамически установить имя файла CSV следующим образом:

<connection id="out" driver="csv" url="my_report_${date:today('yyyyMMdd_HHmmss')}.csv">

Согласно: http://scriptella.org/reference/index.html#%3Cproperties%3E См. "Подстановка выражений и переменных".

Кстати, Scriptella не хватает более структурированной и удобной документации.

person lospejos    schedule 05.11.2019