All Products
Search
Document Center

DataWorks:Advanced notebook development

Last Updated:Jul 17, 2026

Improve development efficiency with code reuse, dataset mounting, and parameter management. Connect to compute engines such as MaxCompute Spark, EMR Serverless Spark, and AnalyticDB for Spark.

Note

We recommend reading Basic Notebook Development.

Environment differences

DataWorks Notebook is a schedulable development and analysis tool that runs in two environments:

  • Development environment: When you run a cell on the DataWorks Notebook editing page in DataStudio, the code runs in a personal development environment instance for rapid validation and debugging.

  • Production environment: After you commit and publish a DataWorks Notebook node, periodic scheduling or data backfill triggers its execution in an isolated, ephemeral task instance for stable and reliable production runs.

Keep these differences in mind when writing code that must work in both environments.

Feature differences

Feature

Development environment (running a cell)

Production environment (periodic scheduling, data backfill)

Referencing project resources (.py)

  • Initial reference: The resource is automatically downloaded and takes effect.

  • After an update: Click the Restart button in the toolbar to reload the updated .py module.

    Important

    In the DataStudio settings, change the Dataworks › Notebook › Resource Reference: Download Strategy setting to autoOverwrite.

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 .py files and reference them as MaxCompute resources using ##@resource_reference{"custom_name.py"}.

  1. Create and publish a Python resource

    1. In the left-side navigation pane of DataWorks DataStudio, click the image icon to go to Resource Management.

    2. 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.

    3. 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!"
    4. In the toolbar, click Save and then Publish. This makes the resource visible to both development and production tasks.

  2. Reference the resource in a notebook

    In the first line of a Python cell in your notebook, use the ##@resource_reference syntax 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)
  3. Debug and run in the development environment

    Run the Python cell. The following result is printed:

    Hello, DataWorks from resource file!
    Important

    When you debug and run in the development environment, the system detects the ##@resource_reference declaration and downloads the target file from Resource Management to workspace/_dataworks/resource_references in your personal directory.

    If a ModuleNotFoundError error occurs, click the Restart button in the editor toolbar to reload the resource, and then try again.

  4. 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.

    Important

    If 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 during notebook task execution.

Debug in the development environment

  1. Mount a dataset: Go to the details page of your personal development environment. In Storage Settings > Datasets, configure the dataset.

  2. 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

  1. 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.

  2. 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

Important

This feature is available only in DataWorks Professional Edition and later.

In addition to scheduling parameters, DataWorks provides Workspace Parameters to reuse global configurations and isolate environments across tasks and nodes. Reference them in SQL and Python cells using ${workspace.param}, where param is the parameter name.

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, prefixed with % or %%, connect a Python cell to compute resources without hard-coding credentials or connection details.

Connect to MaxCompute

Note

Before you connect to a MaxCompute compute resource, ensure you have bound a MaxCompute compute resource.

  • %odps: Get a PyODPS entry object

    This eliminates the need to hard-code an AccessKey in your code.

    1. 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 
    2. 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 connection

    Creates a MaxFrame session for pandas-like distributed processing on 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 multiple Spark engines. Each engine differs in connection method, execution context, and resource lifecycle.

Important

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

%maxcompute_spark

%emr_serverless_spark

%adb_spark add

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

Batch processing and ETL tasks tightly integrated with the MaxCompute ecosystem.

Complex analysis tasks requiring 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

Note

Before you connect to a MaxCompute compute resource, ensure you have bound a MaxCompute compute resource.

Connect to the built-in Spark engine of your MaxCompute project through Livy.

  1. 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
  2. Execute PySpark code: After the connection is established, use the %%spark cell 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()
  3. 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

Note

Before you connect to a compute resource, bind an EMR Serverless Spark compute resource in the workspace and create a Livy Gateway.

Connect to EMR Serverless Spark through an existing Livy Gateway.

  1. 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"
      }
    }
    Note

    Relationship 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.

  2. (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
  3. 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.

    1. 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_spark and 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);
    2. 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|
      +---+-------+-----------+--------+
  4. Manually release the connection

    Important

    If 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

Note

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.

  1. 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>

    How to find the vSwitch ID and security group ID

    • vSwitch ID (vswitchId): Go to the Alibaba Cloud AnalyticDB for MySQL console. On the instance details page, find the vSwitch ID in the Network Information section.

    • security group ID (securityGroupId): Go to the details page of your personal development environment. In the Network Settings section, find the ID of your selected Security Group, which starts with sg-.

      Important

      To ensure network connectivity, we recommend that you select the same VPC and vSwitch as your AnalyticDB for Spark instance when you create a personal development environment.

  2. 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.
  3. Manually release the connection: After debugging, manually clean up the connection session to save resources. In production, resources are automatically cleaned up.

    %adb_spark cleanup

Connect to a Lindorm Ray compute resource

The Lindorm compute engine's Ray resource group provides distributed computing for end-to-end AI workloads. Connect to Lindorm Ray in a notebook for interactive development, then publish the notebook as a scheduled production task.

Before you begin, complete the following steps.

  • When you purchase a Lindorm instance, select Yes for Enable Compute Engine.

  • Add your Lindorm cluster as a DataWorks compute resource. For more information, see Bind a Lindorm compute resource.

  • Enable a Ray resource group for your cluster in the Lindorm console. When creating the resource group, specify the correct image in Advanced Settings to ensure a consistent environment.

    How do I configure the Ray resource group image?

    When you create a Ray resource group in the Lindorm console, find Advanced Settings and enter the following JSON content. Replace region in the image address with the region where your Lindorm cluster is located. For example, replace beijing with shanghai.

    {
      "IMAGE": "spark-repo-beijing-registry-vpc.cn-beijing.cr.aliyuncs.com/lindorm-compute/ray:2.39.0-0.7.0-py311-cpu"
    }
  • Your personal development environment and serverless resource group must be in the same VPC as your Lindorm cluster to ensure network connectivity.

  1. Establish a connection: Run the %lindorm_ray magic 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_ray
    Important
    • 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.

  2. 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.remote decorator. 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))
  3. (Optional) Specify custom startup parameters: To configure additional settings for the Ray environment, such as installing third-party Python packages or uploading local code files, use %%lindorm_ray to establish the connection.

    • Example 1: Install dependencies

      Use the pip parameter to install the jieba package 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 jieba in 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("Welcome to the DataWorks LindormRay solution")))
    • Example 2: Upload and use DataWorks resources

      Use the working_dir parameter to upload resources from Resource Management to the Ray cluster for import in your tasks.

      Important
      • When you use working_dir to 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.

      • For large resources or dependencies (over 100 MB), upload them to OSS and download from OSS in your code, or package them into a custom image for better stability and performance.

      # 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 run the following cell, the system parses the ##@resource_reference declaration and downloads the corresponding resource to /mnt/workspace/_dataworks/resource_references.

      Example code in ray_resource.py:

      def fun():
          print("This is a test function in ray_resource.py")
      Important

      In the development environment, after you run the cell that contains ##@resource_reference, you must rerun the preceding %%lindorm_ray cell. 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("Welcome to the DataWorks LindormRay solution")
      print(ray.get(worker))
  4. Production scheduling and O&M: After development and debugging, 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 production, the system loads only the first 1 MB of logs by default to prevent performance issues. If logs are truncated, the output provides a link to view full task logs in the Lindorm console.

    • Resource release: After a scheduled production task ends, the Lindorm Ray task enters a terminal state and releases resources. During interactive development, terminate the task by restarting the kernel or closing the notebook.

Appendix: Magic command quick reference

Magic command

Description

Compute engine

o = %odps

Gets a PyODPS entry object.

MaxCompute

mf_session = %maxframe

Establishes a MaxFrame connection.

%maxcompute_spark

Creates a Spark session.

MaxCompute Spark

%maxcompute_spark stop

Cleans up the Spark session and stops the Livy session.

%maxcompute_spark delete

Cleans up the Spark session, then stops and deletes the Livy configuration.

%%spark

In a Python cell, connects to an existing Spark compute resource.

%emr_serverless_spark

Creates a Spark session.

EMR Serverless Spark

%emr_serverless_spark info

Views the details of the Livy Gateway.

%emr_serverless_spark stop

Cleans up the Spark session and stops the Livy session.

%emr_serverless_spark delete

Cleans up the Spark session, then stops and deletes the Livy configuration.

%emr_serverless_spark refresh_token

Refreshes the Livy token for the personal development environment.

%adb_spark add

Creates and connects to a reusable ADB Spark session.

AnalyticDB for Spark

%adb_spark info

Views Spark session information.

%adb_spark cleanup

Stops and cleans up the current Spark connection session.

%lindorm_ray

Establishes a Lindorm Ray connection.

Lindorm Ray

%%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 ModuleNotFoundError or There 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 Strategy to autoOverwrite, and then click Restart Kernel in the Notebook toolbar.

  • Q: Why do I get a FileNotFoundError in 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: On the workspace details page, go to the compute resource list. Ensure the compute resource (MaxCompute, EMR, or ADB) is bound to the workspace and 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 vswitchId and securityGroupId are 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.