When you need to pass query results or other outputs from an upstream node to a downstream node, you can use an assignment node. The assignment node (which serves as the upstream node) supports scripts in MaxCompute SQL, Python 2, and Shell. It automatically assigns the last query or output result to the node's output parameter (outputs). Downstream nodes can then reference this parameter to retrieve the output of the assignment node.
Usage notes
Version requirements: This feature is 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 a downstream node.
Upstream assignment node: Generates data. It automatically assigns the last output or query result to a system-generated output parameter named
outputs.Downstream business node: Receives and uses the data. You can configure an input parameter in the node (for example,
param) and set its value to reference theoutputsparameter of the upstream node. This makes the data available to your code.
Parameter format
The following table describes the format of the passed parameters.
Language | Value | Format |
MaxCompute SQL | The output of the last | The node passes the output to downstream nodes as a two-dimensional array. |
Python 2 | The output of the last | DataWorks splits the output string by commas ( For example, if the last line of the assignment node outputs Important If the output itself contains commas, you must escape them. For example, if the output is |
Shell | The output of the last |
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 be used as a downstream node.
Configure the upstream assignment node
In the target workflow, create and edit an assignment node. Select MaxCompute SQL, Python 2, or Shell as needed, and write code to produce the result that you want to pass to a downstream node.
print '10,20,30,40'Configure the downstream Shell node
Create a Shell node. On the editing page of the Shell node, reference the upstream result:
In the Scheduling Settings panel on the right side, select the Node Context Parameters tab.
In the Input Parameters section, click Add parameters.
In the dialog that appears, set the output parameter of the upstream node to the
outputsparameter of the assignment node that you configured in the previous step, and specify a custom Parameter Name for the input parameter of the current node (for example,param).NoteAfter the configuration is complete, the downstream node automatically establishes a dependency on the upstream assignment node.
After the parameter configuration is complete, you can use the value passed from the upstream node in the code of the downstream Shell node by using the
${param}format.
Verify the result
Go back to the workflow and click Deploy on the toolbar. Select full deployment.
Go to the page in Operation Center and perform smoke testing.
In the test instance, check whether the final result meets your expectations.
Create an assignment node by using OpenAPI
In addition to using the console, you can create an assignment node by calling the CreateNode operation of DataWorks OpenAPI. When you create a node by using 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 in 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 the parameters are passed in the same way as the official Alibaba Cloud SDK. Otherwise, the parameters may be passed but the resource group association may not take effect.
Notes
Passing hierarchy: The parameters of an assignment node can only be passed to its immediate downstream child nodes. Cross-level parameter passing is not supported.
Size limit: The maximum size of the passed value is 2 MB. If the output of the assignment statement exceeds this limit, the assignment node fails.
Syntax restrictions:
Comments are not supported in the code of an assignment node. Adding comments may cause unexpected results.
The WITH syntax is not supported in MaxCompute SQL mode.
Examples: Detailed explanation by language
The data format of the output (outputs) and the way downstream nodes reference it vary slightly depending on the language of the assignment node. 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 of data:
SELECT 'beijing', '1001' UNION ALL SELECT 'hangzhou', '1002';Downstream node (Shell node) configuration and output
In the Shell node, add an input parameter named
regionand reference theoutputsparameter 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
typesand reference theoutputsparameter 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
The processing logic for Shell nodes is similar to that for Python 2. It 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, enabling automated data processing with a single set of processing logic that serves multiple product lines.
Background
Assume you are a data development engineer at a comprehensive internet company and are responsible for processing data from three core business lines: e-commerce (ecom), finance (finance), and logistics (logistics), with the possibility of adding more business lines in the future. You need to run the same aggregation logic on the user behavior logs of these three business lines every day to calculate the 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. By using a for-each node, you only need to 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):
Associate a compute resource with the workspace.
Go to Data Studio for data development and create a MaxCompute SQL node.
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';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' );ImportantIf the workspace uses the standard mode, you need to deploy this node to the production environment and backfill data.
Workflow implementation
Create a workflow. In the Scheduling Parameters section on the right side, set the scheduling parameter bizdate to the previous day:
$[yyyymmdd-1].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;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 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.
NoteThis 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;
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 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: When you add a new business line, you only need to add one line of SQL in the assignment node without modifying the processing logic.
Easy maintenance: All business lines share the same set of processing logic. A single modification applies to all business lines.
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
SELECTstatement. Add aSELECTstatement. The WITH syntax is not supported. If you use a WITH statement, this error is also returned.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 (
printorecho).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 & AccessoriesQ: 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.

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 nodes, natively support the assignment parameter feature, which achieves the same effect as an assignment node.
In the Node Output Parameters section, click + Add Assignment Parameter.
References
If the downstream node needs to iterate through and process data in a loop, see Do-while node and For-each node.
If you need to pass parameters across levels, see Virtual node.
For more information about parameter passing configuration, see Node context parameters.