Assignment node

更新时间:
复制 MD 格式

An assignment node passes query results or outputs from an upstream node to downstream nodes. It supports MaxCompute SQL, Python 2, and Shell, and automatically assigns the last query or output result to the node's output parameter (outputs). Downstream nodes reference this parameter to retrieve the result.

Usage notes

  • Version requirements: Available only in DataWorks Standard Edition and later.

  • Permissions: Your RAM account must be added to the target workspace and assigned the developer or workspace administrator role. For more information, see Add members to a workspace.

Key concepts: Parameter passing and referencing

The core function of an assignment node is parameter passing, which transfers data from an upstream node to downstream nodes.

  • Upstream assignment node: Generates data and automatically assigns the last output or query result to a system-generated output parameter named outputs.

  • Downstream business node: Receives and uses the data. Configure an input parameter (for example, param) and set its value to reference the outputs parameter of the upstream node. This makes the data available to your code.

    image

Parameter format

The following table describes the format of passed parameters.

Language

Value

Format

MaxCompute SQL

The output of the last SELECT statement.

The node passes the output to downstream nodes as a two-dimensional array.

Python 2

The output of the last print statement.

DataWorks splits the output string by commas (,) into a one-dimensional array.

For example, if the last line of the assignment node outputs 'Electronics,Clothing,Books', the value passed to downstream nodes is ['Electronics','Clothing','Books'].
Important

If the output itself contains commas, you must escape them. For example, if the output is 'Electronics,Clothing\, Shoes & Accessories', the downstream node correctly parses it as ['Electronics', 'Clothing, Shoes & Accessories'].

Shell

The output of the last echo statement.

Procedure

The following example demonstrates the general procedure by passing the result of an assignment node to a Shell node. In practice, any node type can serve as a downstream node.

  1. Configure the upstream assignment node

    In the target workflow, create and edit an assignment node. Select MaxCompute SQL, Python 2, or Shell, and write code that produces the result you want to pass to a downstream node.

    print '10,20,30,40'
  2. Configure the downstream Shell node

    Create a Shell node. On the editing page of the Shell node, reference the upstream result:

    1. In the Scheduling Settings panel on the right side, select the Node Context Parameters tab.

    2. In the Input Parameters section, click Add parameters.

    3. In the dialog that appears, set the output parameter of the upstream node to the outputs parameter of the assignment node configured in the previous step, and specify a custom Parameter Name for the input parameter of the current node (for example, param).

      Note

      After configuration, the downstream node automatically establishes a dependency on the upstream assignment node.

    4. After parameter configuration, you can use the value passed from the upstream node in the code of the downstream Shell node by using the ${param} format.

  3. Verify the result

    1. Go back to the workflow and click Deploy on the toolbar. Select full deployment.

    2. Go to the Node O&M > Auto Triggered Task O&M > Auto Triggered Task page in Operation Center and perform smoke testing.

    3. In the test instance, check whether the final result meets your expectations.

Create an assignment node by using OpenAPI

You can also create an assignment node by calling the CreateNode operation of DataWorks OpenAPI. When creating a node through the API, configure the node information in the Spec parameter of FlowSpec.

To associate a resource group, specify the resource group identifier in the runtimeResource.resourceGroup field of FlowSpec. Example:

{
  "version": "1.1.0",
  "kind": "Node",
  "spec": {
    "nodes": [
      {
        "recurrence": "Normal",
        "script": {
          "runtime": {
            "command": "CONTROLLER_ASSIGNMENT"
          },
          "content": "print '10,20,30'"
        },
        "runtimeResource": {
          "resourceGroup": "S_res_group_XXX_XXXX"
        },
        "name": "assignment_node_demo"
      }
    ]
  }
}

If you use custom code to call the API, make sure that parameters are passed in the same way as the official Alibaba Cloud SDK. Otherwise, the resource group association may not take effect.

Notes

  • Passing hierarchy: Assignment node parameters can only be passed to immediate downstream child nodes. Cross-level parameter passing is not supported.

  • Size limit: The maximum size of a passed value is 2 MB. If the output exceeds this limit, the assignment node fails.

  • Syntax restrictions:

    • Comments are not supported in assignment node code. Adding comments may cause unexpected results.

    • The WITH syntax is not supported in MaxCompute SQL mode.

Examples: Detailed explanation by language

The output format of outputs and how downstream nodes reference it vary by language. The following examples use a Shell node as the downstream node.

Example 1: Pass MaxCompute SQL query results

SQL query results are passed to downstream nodes as a two-dimensional array.

  • Upstream node (assignment node - SQL) configuration

    Assume the SQL code is as follows and the query returns two rows and two columns:

    SELECT 'beijing', '1001'
    UNION ALL 
    SELECT 'hangzhou', '1002';
  • Downstream node (Shell node) configuration and output

    In the Shell node, add an input parameter named region and reference the outputs parameter of the upstream SQL node.

    Write the following code to read the data:

    echo "Entire result set: ${region}"
    echo "First row: ${region[0]}"
    echo "First row, second field: ${region[0][1]}"

    DataWorks directly parses the parameter and performs static substitution. The output is as follows:

    Entire result set: beijing,1001
    hangzhou,1002
    First row: beijing,1001
    First row, second field: 1001

Example 2: Pass Python 2 output results

The output of the Python 2 print statement is split by commas (,) and passed to downstream nodes as a one-dimensional array.

  • Upstream node (assignment node - Python 2) configuration

    The Python 2 code is as follows:

    print 'Electronics, Clothing, Books';
  • Downstream node (Shell node) configuration and output

    In the Shell node, add an input parameter named types and reference the outputs parameter of the upstream assignment node.

    Write the following code to read the data:

    # Directly output the entire one-dimensional array
    echo "Entire result set: ${types}"
    
    # Output elements by index
    echo "Second element: ${types[1]}"

    DataWorks directly parses the parameter and performs static substitution. The output is as follows:

    Entire result set: Electronics,Clothing,Books
    Second element: Clothing
Note

The processing logic for Shell nodes is similar to Python 2 and is not repeated here.

Scenario: Batch process partition table data across multiple business lines

This example demonstrates how to use an assignment node and a for-each node to batch process user behavior data across multiple business lines, automating data processing with a single set of logic that serves multiple product lines.

image

Background

Assume you are a data development engineer at a comprehensive internet company, responsible for processing data from three core business lines: e-commerce (ecom), finance (finance), and logistics (logistics), with the possibility of adding more in the future. You need to run the same aggregation logic on user behavior logs from these three business lines every day to calculate daily page views (PV) per user and store the results in a unified aggregate table.

  • Upstream source tables (DWD layer):

    • dwd_user_behavior_ecom_d: E-commerce user behavior table.

    • dwd_user_behavior_finance_d: Finance user behavior table.

    • dwd_user_behavior_logistics_d: Logistics user behavior table.

    • dwd_user_behavior_${business_line}_d: User behavior tables for more potential business lines in the future.

    • These tables have the same schema and are partitioned by day (dt).

  • Downstream target table (DWS layer):

    • dws_user_summary_d: User aggregate table.

    • This table is double-partitioned by business line (biz_line) and day (dt) to store the aggregated results from all business lines in a unified manner.

Creating a separate task for each business line results in high maintenance costs and is error-prone. With a for-each node, you maintain a single set of processing logic, and the system automatically iterates through all business lines to complete the computation.

Data preparation

First, create the sample tables and insert test data (using business date 20251010 as an example).

  1. Associate a compute resource with the workspace.

  2. Go to Data Studio for data development and create a MaxCompute SQL node.

  3. Create the source tables (DWD layer): Add the following code to the MaxCompute SQL node and run it.

    -- E-commerce user behavior table
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_ecom_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'E-commerce user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_ecom_d PARTITION (dt='20251010') VALUES
    ('user001', 'click',        1760004060000), -- 2025-10-10 10:01:00.000
    ('user002', 'browse',       1760004150000), -- 2025-10-10 10:02:30.000
    ('user001', 'add_to_cart',  1760004300000); -- 2025-10-10 10:05:00.000
    -- Verify e-commerce user behavior table created successfully
    SELECT * FROM dwd_user_behavior_ecom_d where dt='20251010';
    -- Finance user behavior table
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_finance_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'Finance user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_finance_d PARTITION (dt='20251010') VALUES
    ('user003', 'open_app',      1760020200000), -- 2025-10-10 14:30:00.000
    ('user003', 'transfer',      1760020215000), -- 2025-10-10 14:30:15.000
    ('user003', 'check_balance', 1760020245000), -- 2025-10-10 14:30:45.000
    ('user004', 'open_app',      1760020300000); -- 2025-10-10 14:31:40.000
    -- Verify finance user behavior table created successfully
    SELECT * FROM dwd_user_behavior_finance_d where dt='20251010';
    -- Logistics user behavior table
    CREATE TABLE IF NOT EXISTS dwd_user_behavior_logistics_d (
        user_id     STRING COMMENT 'User ID',
        action_type STRING COMMENT 'Action type',
        event_time  BIGINT COMMENT 'Event timestamp in milliseconds (Unix)'
    ) 
    COMMENT 'Logistics user behavior log detail table'
    PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd');
    INSERT OVERWRITE TABLE dwd_user_behavior_logistics_d PARTITION (dt='20251010') VALUES
    ('user001', 'check_status',    1760032800000), -- 2025-10-10 18:00:00.000
    ('user005', 'schedule_pickup', 1760032920000); -- 2025-10-10 18:02:00.000
    -- Verify logistics user behavior table created successfully
    SELECT * FROM dwd_user_behavior_logistics_d where dt='20251010';
  4. Create the target table (DWS layer): Add the following code to the MaxCompute SQL node and run it.

    CREATE TABLE IF NOT EXISTS dws_user_summary_d (
        user_id     STRING COMMENT 'User ID',
        pv          BIGINT COMMENT 'Daily activity count'
    ) 
    COMMENT 'User daily activity summary table'
    PARTITIONED BY (
        dt           STRING COMMENT 'Date partition, format yyyymmdd',
        biz_line     STRING COMMENT 'Business line partition, e.g. ecom, finance, logistics'
    );
    Important

    If the workspace uses the standard mode, you need to deploy this node to the production environment and backfill data.

Workflow implementation

  1. Create a workflow. In the Scheduling Parameters section on the right side, set the scheduling parameter bizdate to the previous day: $[yyyymmdd-1].

  2. In the workflow, create an assignment node named get_biz_list and write the following code in MaxCompute SQL. This node outputs the list of business lines to be processed:

    -- Output all business lines to be processed
    SELECT 'ecom' AS biz_line
    UNION ALL
    SELECT 'finance' AS biz_line
    UNION ALL
    SELECT 'logistics' AS biz_line;
  3. Configure the for-each node

    • Go back to the workflow page and create a downstream for-each node for the assignment node get_biz_list.

    • Open the for-each node settings page. In the Scheduling Parameters > Script Parameters section under schedule settings on the right side, bind the loopDataArray parameter to the outputs of the get_biz_list node.

    • In the loop body of the for-each node, click Create Internal Node and create a MaxCompute SQL node. Write the processing logic inside the loop body.

      Note
      • This script is driven by the for-each node and is executed once for each business line.

      • The built-in variable ${dag.foreach.current} is dynamically replaced with the current business line name at each iteration. The expected iteration values are: 'ecom', 'finance', 'logistics'.

      SET odps.sql.allow.dynamic.partition=true;
      INSERT OVERWRITE TABLE dws_user_summary_d PARTITION (dt='${bizdate}', biz_line)
      SELECT
          user_id,
          COUNT(*) AS pv,
          '${dag.foreach.current}' AS biz_line
      FROM
          dwd_user_behavior_${dag.foreach.current}_d
      WHERE
          dt = '${bizdate}'
      GROUP BY
          user_id;
  4. Add a verification node

    Go back to the workflow. Click Create Downstream on the for-each node to create a MaxCompute SQL node and add the following code.

    SELECT * FROM dws_user_summary_d WHERE dt='20251010' ORDER BY biz_line, user_id;

Deployment and results

Deploy the workflow to the production environment. Go to the Auto Triggered Task O&M > Auto Triggered Task page in Operation Center. Find the target workflow and perform smoke testing with the business date set to '20251010'.

After the run is complete, view the runtime log in the test instance. The expected output of the final node is as follows:

user_id

pv

dt

biz_line

user001

2

20251010

ecom

user002

1

20251010

ecom

user003

3

20251010

finance

user004

1

20251010

finance

user001

1

20251010

logistics

user005

1

20251010

logistics

Advantages

  • High scalability: To add a new business line, add one line of SQL in the assignment node without modifying the processing logic.

  • Easy maintenance: All business lines share one set of processing logic. A single modification applies to all.

FAQ

  • Q: In MaxCompute SQL mode, the error "find no select sql in sql assignment!" is returned.

    A: The MaxCompute SQL code is missing a SELECT statement. Add a SELECT statement. The WITH syntax is not supported; using a WITH statement also returns this error.

  • Q: In Shell or Python mode, the error "OutPut Result is null, cannot handle!" is returned.

    A: The output is missing. Check whether the code contains a print statement (print or echo).

  • Q: In Shell or Python mode, how do I handle output elements that contain commas?

    A: Escape the commas (,) by using \,. The following example uses Python:

    categories = ["Electronics", "Clothing, Shoes & Accessories"]
    # Escape commas contained in each element
    # Replace ',' with '\,'
    escaped_categories = [cat.replace(",", "\,") for cat in categories]
    # Join escaped elements with commas
    output_string = ",".join(escaped_categories)
    print output_string
    # The final string output to downstream is:
    # Electronics,Clothing\, Shoes & Accessories
  • Q: Can a downstream node receive results from multiple upstream assignment nodes?

    A: Yes. You only need to assign the results of different nodes to different parameters.

    image

  • Q: Does the assignment node support other language types?

    A: The assignment node currently supports only MaxCompute SQL, Python 2, and Shell. Some node types, such as EMR Hive, Hologres SQL, EMR Spark SQL, AnalyticDB for PostgreSQL, ClickHouse SQL, and MySQL, natively support the assignment parameter feature, which achieves the same effect.

    In the Node Output Parameters section, click + Add Assignment Parameter.

References