This guide shows how to improve development efficiency using engineering practices like code reuse, dataset mounting, and parameter management. It also details practical techniques and debugging methods for connecting to compute engines, including MaxCompute Spark, EMR Serverless Spark, and AnalyticDB for Spark.
We recommend reading Basic Notebook Development.
Environment differences
DataWorks Notebook is a schedulable tool for development and analysis. This means it runs in two environments:
-
Development environment: When you run a cell on the DataWorks Notebook editing page in DataStudio, the code executes in a personal development environment instance. This environment is designed for rapid validation and debugging of code logic.
-
Production environment: After you commit and publish a DataWorks Notebook node, its execution is triggered by periodic scheduling or data backfill. The code runs in an isolated, ephemeral task instance. This environment ensures the stable and reliable execution of production tasks.
These two environments differ significantly in feature support. Understanding these differences is key to efficient development.
Feature differences
|
Feature |
Development environment (running a cell) |
Production environment (periodic scheduling, data backfill) |
|
Referencing project resources ( |
|
Takes effect automatically. |
|
Reading and writing datasets (OSS/NAS) |
Mount the dataset in the personal development environment. |
Mount the dataset in the scheduling configurations. |
|
Referencing workspace parameters ( |
Parameters are automatically replaced with their values before code execution. |
Parameters are automatically replaced with their values before task execution. |
|
Spark session management |
The Spark session has a default idle timeout of two hours and is automatically released if it remains idle. |
DataWorks automatically creates and destroys a short-lived session for each task instance. |
Reuse code and data in production
Reference project resources (.py files)
Encapsulate common functions or classes into separate .py files and reference them as MaxCompute resources by using ##@resource_reference{"custom_name.py"}. This approach modularizes your code, improves reusability, and simplifies maintenance.
-
Create and publish a Python resource
-
In the left-side navigation pane of DataWorks DataStudio, click the
icon to go to Resource Management. -
In the Resource Management tree, right-click the target directory or click + in the upper-right corner. Select New Resource > MaxCompute Python, and name the resource
my_utils.py. -
In the Document Content section, click Online Editing, paste your debugged utility function code into the editor, and click Save.
# my_utils.py def greet(name): return f"Hello, {name} from resource file!" -
In the toolbar, click Save and then Publish. This makes the resource visible to both development and production tasks.
-
-
Reference the resource in a notebook
In the first line of a Python cell in your notebook, use the
##@resource_referencesyntax to reference the published resource.##@resource_reference{"my_utils.py"} # If the resource is in a directory, such as my_folder/my_utils.py, you still use ##@resource_reference{"my_utils.py"} without the directory name. from my_utils import greet message = greet('DataWorks') print(message) -
Debug and run in the development environment
Run the Python cell. The following result is printed:
Hello, DataWorks from resource file!ImportantWhen you debug and run in the development environment, the system detects the
##@resource_referencedeclaration and automatically downloads the target file from Resource Management to theworkspace/_dataworks/resource_referencespath in your personal directory. This allows you to reference the file.If a
ModuleNotFoundErrorerror occurs, click the Restart button in the editor toolbar to reload the resource, and then try again. -
Publish to the production environment and verify
After you Save and Publish this Notebook node, go to Operation and Maintenance Center > Auto Triggered Task and click Test to run it. After the task runs successfully, you will see the output
Hello, DataWorks from resource file!in the logs.ImportantIf a
There is no file with id ...error occurs, ensure you have published the Python resource to the production environment first.
For more operations, see MaxCompute resources and functions.
Read and write datasets (OSS/NAS)
Read and write large files stored on OSS or NAS while a notebook task is running.
Debug in the development environment
-
Mount a dataset: Go to the details page of your personal development environment. In Storage Settings > Datasets, configure the dataset.
-
Access in code: The dataset is mounted to the mount path in your personal development environment. You can directly read from or write to this path in your code.
# Assume you have mounted a dataset to /mnt/data/dataset in your personal development environment. import pandas as pd # Use the mount path directly. file_path = '/mnt/data/dataset/testfile.csv' df = pd.read_csv(file_path) # Use PyODPS to write the data to MaxCompute. o = %odps o.write_table('mc_test_table', df, overwrite=True) print(f"Successfully wrote data to the MaxCompute table mc_test_table")
Deploy to production
-
Mount the dataset: In the right-side navigation pane of the notebook node editor, go to Scheduling Settings > Scheduling Policy and add the same dataset.
-
Access in code: After committing and publishing the notebook, the dataset will be mounted to the mount path in the production environment. You can directly read from or write to this path in your code.
# Assume the dataset is mounted to /mnt/data/dataset in the production environment. import pandas as pd # Use the mount path directly. file_path = '/mnt/data/dataset/testfile.csv' df = pd.read_csv(file_path) # Use PyODPS to write the data to MaxCompute. o = %odps o.write_table('mc_test_table', df, overwrite=True) print(f"Successfully wrote data to the MaxCompute table mc_test_table")
For more operations, see Use datasets in a personal development environment.
Reference workspace parameters
This feature is available only in DataWorks Professional Edition and later.
DataWorks introduces Workspace Parameters in addition to the existing scheduling parameters to reuse global configurations and isolate environments across different tasks and nodes. You can reference Workspace Parameters in SQL and Python cells by using the format ${workspace.param}, where param is the name of the Workspace Parameter you created.
1. Create Workspace Parameters: In DataWorks, go to Operation and Maintenance Center > Scheduling Settings > Workspace Parameters to create the parameters.
2. Reference Workspace Parameters:
-
Reference a Workspace Parameter in an SQL cell.
SELECT '${workspace.param}';When the query runs successfully, it prints the resolved value of the parameter.
-
Reference a Workspace Parameter in a Python cell.
print('${workspace.param}')When the code runs successfully, it prints the resolved value of the parameter.
For more details, see Use workspace parameters.
Interact with compute engines using magic commands
Magic commands are special commands prefixed with % or %% that simplify interactions between a Python cell and various compute resources.
Connect to MaxCompute
Before you connect to a MaxCompute compute resource, ensure you have bound a MaxCompute compute resource.
-
%odps: Get a PyODPS entry objectThis is the recommended way to interact with MaxCompute because it avoids hard-coding an AccessKey in your code.
-
Use a magic command to create a MaxCompute connection. Enter
%odps. A MaxCompute compute resource selector appears in the lower-right corner (and automatically selects a compute resource). You can click the MaxCompute project name in the lower-right corner to switch MaxCompute projects.o=%odps -
Use the returned MaxCompute compute resource to run a PyODPS script.
For example, to get all tables in the current project:
with o.execute_sql('show tables').open_reader() as reader: print(reader.raw)
-
-
%maxframe: Establish a MaxFrame connectionThis command creates a MaxFrame session, which provides pandas-like distributed data processing capabilities for MaxCompute.
# Connect to and access the MaxCompute MaxFrame session. mf_session = %maxframe df = mf_session.read_odps_table('your_mc_table') print(df.head()) # After development and debugging, destroy the session to release resources. mf_session.destroy()
Connect to Spark compute resources
DataWorks Notebook supports connections to multiple Spark engines. These engines differ in connection methods, execution contexts, and resource management.
A single notebook node can connect to only one type of compute resource using a magic command.
Engine comparison
|
Feature |
MaxCompute Spark |
EMR Serverless Spark |
AnalyticDB for Spark |
|
Connection command |
|
|
|
|
Note
After you run the command, the execution context of the entire notebook kernel switches to the remote PySpark environment. You can write PySpark code directly in subsequent cells. |
|||
|
Prerequisites |
Bind a MaxCompute compute resource. |
Bind an EMR compute resource and create a Livy Gateway. |
Bind an AnalyticDB for Spark compute resource. |
|
Development environment mode |
Automatically creates or reuses a Livy session. |
Connects to an existing Livy Gateway to create a session. |
Automatically creates or reuses a Spark Connect Server. |
|
Production environment mode |
Livy mode: Submits Spark jobs through the Livy service. |
spark-submit batch mode: Pure batch processing that does not retain session state. |
Spark Connect Server mode: Interacts through the Spark Connect service. |
|
Resource release in production |
The session is automatically released after the task instance ends. |
Resources are automatically cleaned up after the task instance ends. |
Resources are automatically released after the task instance ends. |
|
Use cases |
General-purpose batch processing and ETL tasks that are tightly integrated with the MaxCompute ecosystem. |
Complex analysis tasks that require flexible configurations and interaction with the open-source big data ecosystem, such as Hudi and Iceberg. |
High-performance interactive queries and analysis on C-Store tables of AnalyticDB for MySQL. |
MaxCompute Spark
Before you connect to a MaxCompute compute resource, ensure you have bound a MaxCompute compute resource.
Connect to the Spark engine that is built into your MaxCompute project through Livy.
-
Establish a connection: Run the following command in a Python cell. The system automatically creates or reuses a Spark session.
# Create a Spark Session. %maxcompute_spark -
Execute PySpark code: After the connection is established, use the
%%sparkcell magic to run PySpark code in a new Python cell.# When you use MaxCompute Spark, the Python cell must start with %%spark. %%spark df = spark.sql("SELECT * FROM your_mc_table LIMIT 10") df.show() -
Manually release the connection: After development and debugging, you can manually stop or delete the session. When running in a production environment, the system automatically stops and deletes the Livy session for the current task instance.
# Clean up the Spark session and stop the Livy session. %maxcompute_spark stop # Clean up the Spark session, then stop and delete the Livy configuration. %maxcompute_spark delete
EMR Serverless Spark
Before you connect to a compute resource, bind an EMR Serverless Spark compute resource in the workspace and create a Livy Gateway.
Interact with EMR Serverless Spark by connecting to an existing Livy Gateway.
-
Establish a connection: Before you run the command, you must select the EMR compute resource and Livy Gateway in the lower-right corner of the cell.
# Basic connection %emr_serverless_spark # Or, to pass custom Spark parameters at connection time, use two percent signs (%%). %%emr_serverless_spark { "spark_conf": { "spark.emr.serverless.environmentId": "<EMR_Serverless_Spark_runtime_environment_ID>", "spark.emr.serverless.network.service.name": "<EMR_Serverless_Spark_network_connection_ID>", "spark.driver.cores": "1", "spark.driver.memory": "8g", "spark.executor.cores": "1", "spark.executor.memory": "2g", "spark.driver.maxResultSize": "32g" } }NoteRelationship between custom parameters and global configurations
-
Default behavior: Custom parameters defined here apply only to the current session. If you do not provide custom parameters, the system uses the global parameters configured in the Admin Center.
-
Recommended usage: For configurations that need to be reused across multiple tasks or by multiple users, we recommend configuring them globally in Admin Center > Serverless Spark > SPARK parameters to ensure consistency and simplify management.
-
Priority rule: When the same parameter is set in both custom parameters and the global configuration, the GlobalConfiguration Priority option in the Admin Center determines which setting takes effect.
-
If selected: The global configuration overrides the custom parameters for this session.
-
If not selected: The custom parameters for this session override the global configuration.
-
-
-
(Optional) Reconnect: If an administrator accidentally deletes the token from the Livy Gateway page, you can run the following command to recreate it.
# Reconnect and refresh the Livy token for the current personal development environment. %emr_serverless_spark refresh_token -
Execute PySpark or SQL code: After a successful connection, the kernel switches. You can write PySpark code directly in a Python cell or write SQL in an EMR Spark SQL cell.
-
Submit and execute SQL code on the compute resource in an EMR Spark SQL cell
After you establish a connection using
%emr_serverless_spark, you can directly write SQL statements in an EMR Spark SQL cell without selecting a compute resource in the cell.The EMR Spark SQL cell reuses the connection from
%emr_serverless_sparkand submits the code to the target compute resource for execution.INSERT INTO employees VALUES (6, 'Fiona', 'Engineering', 98000.0), (7, 'George', 'Sales', 77000.0), (8, 'Hannah', 'Marketing', 72000.0), (9, 'Ian', 'Engineering', 105000.0), (10, 'Julia', 'HR', 68000.0); -
Submit and execute PySpark code on the compute resource using Python
After you establish a connection using
%emr_serverless_spark, you can submit and execute PySpark code in a new Python cell. You do not need to add the %%spark prefix in the cell.df = spark.sql("SELECT * FROM employees;") df.show() +---+-------+-----------+--------+ | id| name| department| salary| +---+-------+-----------+--------+ | 1| Alice|Engineering| 95000.0| | 2| Bob| Marketing| 75000.0| | 3|Charlie|Engineering|110000.0| | 4| Diana| HR| 70000.0| | 5| Evan| Sales| 80000.0| | 6| Fiona|Engineering| 98000.0| | 7| George| Sales| 77000.0| | 8| Hannah| Marketing| 72000.0| | 9| Ian|Engineering|105000.0| | 10| Julia| HR| 68000.0| +---+-------+-----------+--------+
-
-
Manually release the connection
ImportantIf multiple users share a Livy Gateway, the stop or delete command affects all users who are using the gateway. Use these commands with caution.
# Clean up the Spark session and stop the Livy session. %emr_serverless_spark stop # Clean up the Spark session, then stop and delete the Livy configuration. %emr_serverless_spark delete
AnalyticDB for Spark
Before you connect to the compute resource, bind an AnalyticDB for Spark compute resource in the workspace.
Connect to an AnalyticDB for Spark engine by creating a Spark Connect Server.
-
Establish a connection: To ensure network connectivity, you must correctly configure the vSwitch ID and security group ID in the connection parameters. Before you run the command, select the ADB Spark compute resource in the lower-right corner of the cell.
# You must configure the vSwitch ID and security group ID to establish a network connection. %adb_spark add \ --spark-conf spark.adb.version=3.5 \ --spark-conf spark.adb.eni.enabled=true \ --spark-conf spark.adb.eni.vswitchId=<vSwitch_ID_of_ADB> \ --spark-conf spark.adb.eni.securityGroupId=<security_group_id_of_your_personal_development_environment> -
Execute PySpark code: After the connection is successful, run PySpark code in a new Python cell.
# You can run operations only on C-Store tables. df = spark.sql("SELECT * FROM my_adb_cstore_table LIMIT 10") df.show()Note: The AnalyticDB for Spark engine can currently process only C-Store tables that have the
'storagePolicy'='COLD'attribute. -
Manually release the connection: After you finish debugging in the development environment, manually clean up the connection session to save resources. In a production environment, resources are automatically cleaned up.
%adb_spark cleanup
Connect to a Lindorm Ray compute resource
The Ray resource group of the Lindorm compute engine provides distributed computing services that support end-to-end AI workloads. Using a magic command, you can seamlessly connect to Lindorm Ray resources in a notebook for interactive development and debugging, and then publish the notebook as a production scheduling task.
-
Establish a connection: Run the
%lindorm_raymagic command in a Python cell. After you run the command, a compute resource selector appears in the lower-right corner of the cell. Select your Lindorm compute resource and the Ray resource group you created.# Connect to the specified Lindorm Ray resource group. %lindorm_rayImportant-
After you connect to a Lindorm Ray compute resource, you can no longer run SQL cells in the same notebook. The Lindorm Ray engine focuses on running Python and Ray code.
-
If you run the same code cell multiple times, the system automatically terminates the previous Ray job and starts a new one. This prevents resource waste and task conflicts.
-
-
Execute Ray code: After a successful connection, you can directly write and run Ray code in a new Python cell. Logs are streamed to the output area of the cell in real time for interactive debugging.
The following example defines a simple remote task using the
@ray.remotedecorator. The task runs on the Ray cluster, and the logs and final result are returned to the output area of the cell.import ray import time @ray.remote def hello_world(): print("Hello from Lindorm Ray!") time.sleep(5) return "Task finished." # Submit the remote task. result_ref = hello_world.remote() print(ray.get(result_ref)) -
(Optional) Specify custom startup parameters: If you need to specify additional configurations for the Ray environment, such as installing third-party Python packages or uploading local code files, use the
%%lindorm_raycommand to establish the connection.-
Example 1: Install dependencies
Use the
pipparameter to install thejiebapackage in the Ray environment.%%lindorm_ray { "runtime_env": { "pip": ["jieba"] } }After the environment is ready, import and use the package in subsequent Ray tasks. The following example shows how to call
jiebain a remote function for Chinese word segmentation:import ray @ray.remote def do_work(x): import jieba return "/".join(jieba.cut(x)) print(ray.get(do_work.remote("欢迎使用DataWorks+LindormRay解决方案"))) -
Example 2: Upload and use DataWorks resources
Use the
working_dirparameter to upload resources from Resource Management to the Ray cluster, so they can be imported and called in your tasks.Important-
When you use
working_dirto upload resources, the files are uploaded directly from your development environment to the Ray cluster. A size limit of 100 MB applies. If the resource package is too large, the upload may fail or the Ray node may become unstable.
# Reference and declare the path for a resource from Resource Management. %%lindorm_ray { "runtime_env": { "working_dir": "/mnt/workspace/_dataworks/resource_references" } }Assume that you have uploaded a file named ray_resource.py to Resource Management in DataWorks. When you write and run the following cell, the system automatically parses the
##@resource_referencedeclaration in the subsequent code and downloads the corresponding resource to the/mnt/workspace/_dataworks/resource_referencespath.ImportantIn the development environment, after you run the cell that contains ##@resource_reference, you must rerun the preceding
%%lindorm_raycell. Rerunning this cell includes the downloaded resources in the working_dir and uploads them to the Ray cluster. You do not need to rerun the cell in the production environment.import ray ##@resource_reference{"ray_resource.py"} @ray.remote def do_work(x): print('Ray says:', x) from ray_resource import fun fun() return x worker = do_work.remote("欢迎使用DataWorks+LindormRay解决方案") print(ray.get(worker)) -
-
-
Production scheduling and O&M: After development and debugging, you can commit and publish this notebook node. It will be scheduled periodically as a Lindorm Ray node in a DAG.
-
Parameterization: Your code can use standard DataWorks scheduling parameters, such as
${bizdate}. -
Log viewing: In a production environment, to prevent excessive logs from affecting performance, the system loads only the first 1 MB of logs by default. If the logs are truncated, the output provides a link that you can click to view the complete task logs in the Lindorm console.
-
Resource release: After a scheduled production task ends, the Lindorm Ray task enters a terminal state and no longer occupies resources. During interactive development, you can terminate the Lindorm Ray task by restarting the kernel or closing the notebook.
-
Appendix: Magic command quick reference
|
Magic command |
Description |
Compute engine |
|
|
Gets a PyODPS entry object. |
MaxCompute |
|
|
Establishes a MaxFrame connection. |
|
|
|
Creates a Spark session. |
MaxCompute Spark |
|
|
Cleans up the Spark session and stops the Livy session. |
|
|
|
Cleans up the Spark session, then stops and deletes the Livy configuration. |
|
|
|
In a Python cell, connects to an existing Spark compute resource. |
|
|
|
Creates a Spark session. |
EMR Serverless Spark |
|
|
Views the details of the Livy Gateway. |
|
|
|
Cleans up the Spark session and stops the Livy session. |
|
|
|
Cleans up the Spark session, then stops and deletes the Livy configuration. |
|
|
|
Refreshes the Livy token for the personal development environment. |
|
|
|
Creates and connects to a reusable ADB Spark session. |
AnalyticDB for Spark |
|
|
Views Spark session information. |
|
|
|
Stops and cleans up the current Spark connection session. |
|
|
|
Establishes a Lindorm Ray connection. |
Lindorm Ray |
|
|
Establishes a Lindorm Ray connection and configures a custom runtime environment, such as installing dependencies or uploading code. |
FAQ
-
Q: Why do I get a
ModuleNotFoundErrororThere is no file with id ...error when referencing a workspace resource?A: Check the following:
-
Navigate to Data Development > Resource Management and ensure the MaxCompute Python resource is saved. If this error occurs in the production environment, confirm that the resource has also been published.
-
Click the Restart button in the Notebook editor toolbar to reload the resource.
-
-
Q: After I update a workspace resource, why does the Notebook still use the old version?
A: In DataStudio settings, set
DataWorks › Notebook › Resource Reference: Download Strategyto autoOverwrite, and then click Restart Kernel in the Notebook toolbar. -
Q: Why do I get a
FileNotFoundErrorin the development environment when referencing a dataset?A: Ensure the dataset is mounted in the selected personal development environment.
-
Q: Referencing a dataset works in the development environment but fails in the production environment with the error
Execute mount dataset exception! Please check your dataset config.A: Ensure the dataset is mounted in the Scheduling Settings of the Notebook node and that the OSS dataset has been authorized.
In the dataset configuration area, if a red message "The current DataWorks resource group is not authorized" appears below the dataset dropdown list, click the Confirm Authorization link to the right to grant the permissions.
-
Q: How do I check the version of my personal development environment?
A: In your personal development environment, press CMD+SHIFT+P and enter "ABOUT" to view the current version. If a feature requires version 0.5.69 or later, you can use the One-click Upgrade option in the upgrade prompt that appears.
-
Q: Why does the connection to the Spark engine fail?
A: Follow these steps to troubleshoot the issue:
-
General checks: Navigate to the compute resource list on the workspace details page. Ensure the compute resource (MaxCompute, EMR, or ADB) is bound to the workspace and that your account has the necessary permissions.
-
EMR Serverless Spark: Verify that the Livy Gateway has been created and is running correctly.
-
AnalyticDB for Spark: Focus on troubleshooting network issues. Ensure the
vswitchIdandsecurityGroupIdare configured correctly and that network connectivity exists between the personal development environment and the AnalyticDB for Spark instance. Check the security group rules to ensure they allow communication on the necessary ports.
-