Use PyODPS in a local environment

Updated at:

PyODPS is the Python SDK for MaxCompute. It provides basic operations on MaxCompute objects and a DataFrame framework, enabling you to use Python for big data processing and analysis in DataWorks or a local environment. This topic shows you how to install PyODPS, connect to MaxCompute, run SQL queries, and use the DataFrame API in a local environment.

Prerequisites

Before you begin, ensure you meet the following requirements:

  • Python 3.6 or later is installed.

  • You have an Alibaba Cloud account and an access key to connect to your MaxCompute project. We recommend using the access key of a RAM user.

Install PyODPS

  1. Install PyODPS

    • Linux/macOS:

      pip3 install pyodps
    • Windows:

      pip install pyodps

    If you encounter C code compilation errors when installing dependencies such as numpy or pyarrow, your pip or setuptools version might be outdated. Upgrade them and retry the installation:

    # Linux/macOS
    pip3 install -U pip setuptools
    
    # Windows
    pip install -U pip setuptools
  2. Verify the installation

    • Linux/macOS:

      python3 -c "from odps import ODPS"
    • Windows:

      python -c "from odps import ODPS"

      If no error is reported, the installation is successful. If an error occurs, see Troubleshooting.

Set environment variables

To avoid hard-coding your credentials in your code, set them as environment variables.

Log on to the RAM console, copy your access key ID and secret access key, and then configure them based on your operating system. For example, on macOS (zsh):

  1. macOS (zsh):

    vim ~/.zshrc
  2. Add the following lines and replace the placeholders with your actual values

    export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-AccessKey-ID>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-AccessKey-secret>
  3. Apply the configuration

    source ~/.zshrc
  4. Verify that the environment variables are set

    echo $ALIBABA_CLOUD_ACCESS_KEY_ID
    echo $ALIBABA_CLOUD_ACCESS_KEY_SECRET

    Each command should output its corresponding value. If the output is empty, repeat steps 2 and 3.

For details on setting environment variables on Linux, macOS, and Windows, see Set the Alibaba Cloud access key in an environment variable.

Initialize the ODPS entry point

The ODPS class is the entry point for all PyODPS operations. It must be initialized with credential and project information before you call any other API.

Before you run the code, make sure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are set. You can also explicitly specify your access key, but this is not recommended because hard-coding credentials in source code poses a security risk.

To obtain an access key ID and a secret access key, see Obtain an access key ID and a secret access key.

Manual definition

The following code shows how to manually define the ODPS entry point:

  • Recommended (using environment variables)

    import os
    from odps import ODPS
    
    o = ODPS(
        access_id=os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
        secret_access_key=os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
        project='your-default-project',
        endpoint='your-end-point',
    )
  • Not recommended (explicitly specified for testing only)

    import os
    from odps import ODPS
    
    o = ODPS(
        access_id='your-aliyun-access-key-id',
        secret_access_key='your-aliyun-access-key-secret',
        project='your-default-project',
        endpoint='your-end-point',
    )
    

Use an STS security credential

If you use an STS security credential to access ODPS, initialize the ODPS entry point object as follows:

import os
from odps import ODPS
from odps.accounts import StsAccount
# Make sure the ALIBABA_CLOUD_ACCESS_KEY_ID environment variable is set to your access key ID,
# the ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variable is set to your secret access key,
# and the ALIBABA_CLOUD_STS_TOKEN environment variable is set to your STS token.
# For security, avoid hard-coding your access key ID or secret access key.
account = StsAccount(
    os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
    os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
    os.getenv('ALIBABA_CLOUD_STS_TOKEN'),
)
o = ODPS(
    account=account,
    project='**your-default-project**',
    endpoint='**your-end-point**',
)

Parameter

Description

your-default-project

The name of your MaxCompute project. Log on to the MaxCompute console to view a list of your projects.

your-end-point

The endpoint for your region and network environment. For a list of endpoints, see Endpoints.

For example, the public network endpoint for the China (Hangzhou) region is https://service.cn-hangzhou.maxcompute.aliyun.com/api.

After completing these configurations, you can use PyODPS in your local environment. For more information, see Overview of basic operations.

Process data

SQL

MaxCompute supports two SQL execution modes: traditional mode and MaxCompute Query Acceleration (MaxQA) mode. Both modes support DDL and DML statements. MaxQA caches job results and returns the cached results to accelerate repeated queries. For information about billing rules, see Compute costs (Pay-As-You-Go).

The execute_sql() and run_sql() methods support only DDL and DML statements. For other statement types, use their dedicated methods. For example, use the create_table() method for CREATE TABLE statements, and use the run_xflow() or execute_xflow() methods for API commands.

Traditional mode

Use execute_sql() to run an SQL statement and open_reader() to read the results:

# Use the dedicated method to create a table
o.create_table('my_t', 'num bigint, id string', if_not_exists=True)

# Run a SELECT query
result = o.execute_sql('SELECT * FROM pyodps_iris LIMIT 3')
with result.open_reader() as reader:
    for record in reader:
        print(record)

MaxQA mode

MaxCompute Query Acceleration (MaxQA) is a MaxCompute feature that accelerates queries on small- to medium-sized data by using a dedicated resource pool. Starting from PyODPS v0.11.4.1, you can use execute_sql_interactive to run SQL queries through MaxQA.

o.execute_sql_interactive('SELECT * FROM dual', fallback='all')

If MaxQA cannot run the SQL statement, the system automatically falls back to traditional mode. To disable this fallback, set the fallback parameter to False. You can also specify a fallback policy as a comma-separated string:

Fallback policy

Description

generic

Falls back to traditional mode when an unknown error occurs.

noresource

Falls back to traditional mode when resources are insufficient.

upgrading

Falls back to traditional mode during a system upgrade.

timeout

Falls back to traditional mode when a timeout occurs.

unsupported

Falls back to traditional mode for unsupported scenarios.

The default policy is unsupported,upgrading,noresource,timeout. To ensure that fallback is always enabled, set it to all, which is an alias for generic,unsupported,upgrading,noresource,timeout.

# Fall back only when resources are insufficient or the scenario is unsupported
o.execute_sql_interactive('SELECT * FROM dual', fallback="noresource,unsupported")

For more details about SQL operations in PyODPS, see SQL.

DataFrame

PyODPS provides a DataFrame API for data processing.

Unlike pandas, PyODPS DataFrames are lazy-evaluated. This means a computation is performed only when you call an immediate execution method, such as execute() or persist().

from odps.df import DataFrame

# Load the pyodps_iris table into a DataFrame
iris = DataFrame(o.get_table('pyodps_iris'))

# Filter rows and print the results. The .execute() method triggers the actual computation.
for record in iris[iris.sepalwidth < 3].execute():
    print(record)

By default, PyODPS running locally does not print detailed logs similar to Logview. To enable verbose output:

from odps import options
options.verbose = True

Runtime parameters (hints)

You can set runtime parameters for a single query by passing a hints dictionary to the SQL call:

o.execute_sql('SELECT * FROM pyodps_iris', hints={'odps.sql.mapper.split.size': 16})

To apply hints to all SQL calls in a session, you can configure them globally:

from odps import options

# All subsequent execute_sql() calls will automatically include these hints
options.sql.settings = {'odps.sql.mapper.split.size': 16}
o.execute_sql('SELECT * FROM pyodps_iris')

Complete example

The following example demonstrates the complete process: connecting to MaxCompute, creating a table, writing data, reading data, querying the my_new_table table, and cleaning up resources.

This example calls table.drop() at the end, which permanently deletes the my_new_table table. To avoid data loss, do not use an existing table name, as this script drops the table. If you want to keep the table created by this script, remove the final table.drop() call.

  1. Create a local file named test-pyodps-local.py.

  2. Add the following code:

    import os
    from odps import ODPS
    
    o = ODPS(
        access_id=os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
        secret_access_key=os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
        project='your-default-project',
        endpoint='your-end-point',
    )
    
    table = o.create_table('my_new_table', 'num bigint, id string', if_not_exists=True)
    
    records = [[111, 'aaa'],
               [222, 'bbb'],
               [333, 'ccc'],
               [444, 'non_ascii_text']]
    o.write_table(table, records)
    
    # Read the records
    for record in o.read_table(table):
        print(record[0], record[1])
    
     # Use SQL to query the my_new_table table
    result = o.execute_sql('SELECT * FROM my_new_table;')
    
    
    print('Read data from my_new_table using open_reader:')
    
    # Print the query results
    with result.open_reader() as reader:
        for record in reader:
            print(record[0], record[1])
    
    # Drop the table to release resources
    table.drop()
  3. Run the script

    python test-pyodps-local.py

    Expected output:

    111 aaa
    222 bbb
    333 ccc
    444 non_ascii_text
    Read data from my_new_table using open_reader:
    111 aaa
    222 bbb
    333 ccc
    444 non_ascii_text

Troubleshooting

Dependency installation error

  • Symptom: A C code compilation error occurs when you install dependencies such as numpy or pyarrow.

  • Cause: Your pip or setuptools version is outdated.

  • Solution: Upgrade pip and setuptools, and then reinstall PyODPS.

    # Linux/macOS
    pip3 install -U pip setuptools
    
    # Windows
    pip install -U pip setuptools

pip version conflict with multiple Python versions

  • Symptom: PyODPS is installed for the wrong version of Python.

  • Cause: Your system has multiple versions of Python, and pip3 points to a different version than your intended one.

  • Solution: Invoke pip through the specific Python executable you want to use.

    /home/tops/bin/python3.7 -m pip install pyodps

    Replace /home/tops/bin/python3.7 with the path to your target Python installation.

urllib3 OpenSSL version error

  • Symptom: The installation fails with the error message urllib3 v2.0 only supports OpenSSL 1.1.1+.

  • Cause: Your Python installation uses an older version of OpenSSL that is incompatible with urllib3 v2.0.

  • Solution: Install an earlier version of urllib3 before installing PyODPS.

    # Linux/macOS
    pip3 install "urllib3<2.0"
    
    # Windows
    pip install "urllib3<2.0"