Los nodos ODPS Script permiten desarrollar tareas de MaxCompute en modo script mediante el motor SQL de MaxCompute V2.0. En este modo, un archivo de script SQL completo (que incluye varias instrucciones) se compila como una sola unidad y se envía a MaxCompute como un único plan de ejecución. Todas las instrucciones se ejecutan en una sola cola, lo que permite a MaxCompute optimizar el procesamiento entre instrucciones y aprovechar al máximo los recursos disponibles.
Requisitos previos
Antes de empezar, asegúrese de cumplir con lo siguiente:
Haber creado un nodo ODPS Script en DataWorks. Para más detalles, consulte Crear y gestionar nodos ODPS.
Cuándo usar el modo script
Utilice el modo script cuando necesite:
Reescribir una sola instrucción con subconsultas anidadas en varias instrucciones más simples que compartan resultados intermedios.
Dividir un script complejo en varias instrucciones conectadas mediante variables.
El modo script no es adecuado cuando los datos de múltiples orígenes presentan grandes diferencias de tiempo en su disponibilidad. Por ejemplo, si el origen A está listo a la 01:00 y el origen B a las 07:00, las variables de tabla no pueden empaquetar estas instrucciones de manera eficiente en un solo script.
Para obtener más contexto, consulte SQL en modo script.
Sintaxis del script
Un script de MaxCompute puede contener instrucciones SET, instrucciones DDL e instrucciones DML. Cada tipo puede aparecer cero o más veces, pero no se pueden mezclar tipos de instrucciones.
La estructura general es la siguiente:
-- SET statements
set odps.sql.type.system.odps2=true;
[set odps.stage.reducer.num=***;]
[...]
-- DDL statements
create table table1 xxx;
[create table table2 xxx;]
[...]
-- DML statements
@var1 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table3
[WHERE where_condition];
@var2 := SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table4
[WHERE where_condition];
@var3 := SELECT [ALL | DISTINCT] var1.select_expr, var2.select_expr, ...
FROM @var1 join @var2 on ...;
INSERT OVERWRITE|INTO TABLE [PARTITION (partcol1=val1, partcol2=val2 ...)]
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM @var3;
[@var4 := SELECT [ALL | DISTINCT] var1.select_expr, var.select_expr, ... FROM @var1
UNION ALL | UNION
SELECT [ALL | DISTINCT] var1.select_expr, var.select_expr, ... FROM @var2;
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
AS
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM var4;]
Sintaxis de variables
Asigne los resultados de una consulta a una variable mediante el operador :=:
@<variable_name> := <SELECT statement>;
|
Elemento |
Descripción |
|
|
Nombre de la variable con el prefijo |
|
|
Operador de asignación. Asigna el resultado de SELECT a la variable como un conjunto de resultados de tabla. |
|
|
Cualquier instrucción SELECT válida. |
Para asignar una constante a una variable y usarla como valor escalar, combine SELECT <constant> con una instrucción posterior SELECT * FROM @variable. Por ejemplo:
@a := SELECT 10; -- Assign the constant 10 to @a. You can also use SELECT col1 FROM t1 to assign a value from a single-row table.
@b := SELECT key, value + (SELECT * FROM @a) FROM t2 WHERE key > 10000;
SELECT * FROM @b;
Para obtener más información sobre esta sintaxis, consulte Subqueries.
Limitaciones
Se aplican las siguientes limitaciones al escribir código para nodos ODPS Script.
Tipos de instrucciones compatibles
Los nodos ODPS Script admiten instrucciones SET, instrucciones DML y un subconjunto de instrucciones DDL. Las instrucciones DDL que muestran resultados (como DESC y SHOW) no son compatibles.
Instrucciones que muestran resultados
Escriba como máximo una instrucción que muestre resultados (como una instrucción SELECT) por script. Escribir varias instrucciones de este tipo provoca un error.
Error:
SELECT * FROM src1;
SELECT * FROM src2; -- Second result-displaying statement causes an error.
Solución: Conserve solo una instrucción SELECT que muestre resultados o evite por completo el uso de instrucciones SELECT de visualización en scripts de producción.
CREATE TABLE AS
Escriba como máximo una instrucción CREATE TABLE AS por script y colóquela como la última instrucción. Para facilitar el mantenimiento de los scripts, escriba las instrucciones CREATE TABLE y las instrucciones INSERT en secciones separadas.
Comportamiento ante fallos del script
Si alguna instrucción del script falla, todo el script falla.
Generación de trabajos
MaxCompute genera un trabajo para el script solo después de que todos los datos de entrada estén listos.
Escritura y lectura en el mismo script
Escribir datos en una tabla y luego leerlos en el mismo script provoca un error.
Error:
insert overwrite table src2 select * from src where key > 0;
@a := select * from src2; -- Reading from the table written above causes an error.
select * from @a;
Solución: Utilice una variable para almacenar el resultado intermedio en lugar de escribir y leer la misma tabla:
@a := select * from src where key > 0;
insert overwrite table src2 select * from @a;
select * from @a;
Ejemplo básico
El siguiente script combina varias tablas de origen y escribe los resultados en dos tablas de destino. Los resultados intermedios se almacenan en variables, por lo que no es necesario gestionar manualmente el orden de ejecución de las instrucciones.
create table if not exists dest(key string, value bigint);
create table if not exists dest2(key string, value bigint);
@a := select * from src where value > 0;
@b := select * from src2 where key is not null;
@c := select * from src3 where value is not null;
@d := select a.key, b.value from @a left outer join @b on a.key = b.key and b.value > 0;
@e := select a.key, c.value from @a inner join @c on a.key = c.key;
@f := select * from @d union select * from @e union select * from @a;
insert overwrite table dest select * from @f;
@g := select e.key, c.value from @e join @c on e.key = c.key;
insert overwrite table dest2 SELECT * from @g;
Este ejemplo utilizasrc,src2ysrc3como tablas de origen. Para crearlas con datos de muestra:
create table if not exists src(key string, value BIGINT);
insert into src values ('1', 11);
insert into src values ('1', 11);
create table if not exists src2(key string, value BIGINT);
insert into src2 values ('1', 22);
insert into src2 values ('2', 22);
create table if not exists src3(key string, value BIGINT);
insert into src3 values ('1', 33);
insert into src3 values ('3', 33);
Una vez ejecutado el script, dest contiene la unión de todas las filas filtradas y combinadas, mientras que dest2 contiene las filas resultantes de la combinación interna (inner join) de @e y @c.
Ejemplos avanzados
Instrucción IF con una expresión BOOLEAN
Cuando la condición IF es una expresión de tipo BOOLEAN, la rama se determina en el momento de compilación del código. MaxCompute evalúa la condición durante la compilación y selecciona la rama antes de enviar el trabajo.
set odps.sql.allow.fullscan=true;
set odps.optimizer.cbo.rule.filter.black=LM;
@date := '${var}';
@row TABLE(key int, value bigint); -- Declare a table variable with schema (key int, value bigint).
IF (cast(@date as bigint) % 2 == 0) BEGIN
@row := SELECT key, value from src1;
END ELSE BEGIN
@row := SELECT key, value from src2;
END
INSERT OVERWRITE TABLE dest1 partition(p='${var}') SELECT key, value FROM @row;
La variable var utilizada en el script debe tener un valor asignado en la sección Scheduling Parameter de la pestaña Properties .
Cuando var es 2 (un número par), MaxCompute selecciona la rama src1 en tiempo de compilación e inserta las filas de src1 en dest1. Cuando var es 3 (un número impar), inserta en su lugar las filas de src2.
Instrucción IF con una subconsulta escalar de tipo BOOLEAN
Cuando la condición IF es una subconsulta escalar de tipo BOOLEAN, la rama se determina en el momento de ejecución del trabajo, no durante la compilación. MaxCompute debe enviar varios trabajos para evaluar la condición.
@i bigint;
@t table(id bigint, value bigint);
IF ((SELECT count(*) FROM src WHERE a = '5') > 1) BEGIN
@i := 1;
@t := select @i, @i*2;
END ELSE
BEGIN
@i := 2;
@t := select @i, @i*2;
END
select id, value from @t;
Si src contiene más de una fila donde a = '5', el script establece @i en 1 y @t en (1, 2). De lo contrario, establece @i en 2 y @t en (2, 4).
UDF integradas en el código
El modo script permite integrar código Java o Python directamente en un script SQL para implementar funciones definidas por el usuario (UDF). Para más detalles, consulte UDF integradas en el código.
Siguientes pasos
Una vez completado el desarrollo del nodo, siga estos pasos para poner la tarea en producción.
|
Paso |
Descripción |
|
Configurar la programación |
Establezca el comportamiento de reejecución, los ciclos de programación y las dependencias de tareas para que DataWorks ejecute la tarea según un programa. Consulte Descripción general. |
|
Depurar el nodo |
Ejecute el código en DataWorks para comprobar la lógica antes del despliegue. Si el resultado no coincide con lo esperado, corrija el código y vuelva a ejecutarlo. Consulte Procedimiento de depuración. |
|
Desplegar el nodo |
Despliegue el nodo para activar la programación periódica según las propiedades configuradas. Tras el despliegue, DataWorks programa la tarea automáticamente. Consulte Desplegar nodos. |