すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:Python SDK に関する FAQ

最終更新日:Jul 07, 2025

このトピックでは、Python SDK(PyODPS)についてよくある質問(FAQ)を説明します。

問題のカテゴリ

FAQ

PyODPS のインストール

モジュールのインポート

PyODPS の使用

PyODPS をインストールするときに「警告:XXX がインストールされていません」というエラーメッセージが表示された場合はどうすればよいですか?

この問題は、コンポーネントが不足していることが原因で発生します。エラーメッセージの XXX 情報から不足しているコンポーネントの名前を特定し、pip コマンドを使用してインストールします。

PyODPS をインストールするときに「プロジェクトが見つかりません」というエラーメッセージが表示された場合はどうすればよいですか?

この問題の原因は次のとおりです。

  • エンドポイントの構成が正しくありません。ターゲットプロジェクトのエンドポイントに変更する必要があります。エンドポイントの詳細については、「エンドポイント」をご参照ください。

  • MaxCompute エントリオブジェクトのパラメーターの位置が無効です。正しく入力されていることを確認してください。MaxCompute エントリオブジェクトパラメーターの詳細については、「PyODPSのインストール」をご参照ください。

PyODPS をインストールするときに「構文エラー」というエラーメッセージが表示された場合はどうすればよいですか?

このエラーは、サポートされていない Python バージョンが原因で発生します。Python 2.5 以前はサポートされていません。Python 2.7.6 以降のマイナーバージョン、Python 3.3 以降のマイナーバージョン、Python 2.6 など、PyODPS でサポートされているメインストリームバージョンを使用してください。

macOS で PyODPS をインストールするときに「権限が拒否されました」というエラーメッセージが表示された場合はどうすればよいですか?

PyODPS をインストールするには、sudo pip install pyodps コマンドを使用します。

macOS で PyODPS をインストールするときに「操作は許可されていません」というエラーメッセージが表示された場合はどうすればよいですか?

このエラーは、システム整合性保護(SIP)が原因で発生します。解決するには、デバイスを再起動し、起動プロセス中に [⌘] + [R] を押します。その後、ターミナルで以下のコマンドを実行します。

csrutil disable
reboot       

詳細については、「root で操作が許可されていません - El Capitan(rootless 無効)」をご参照ください。

from odps import ODPS コードを実行するときに「ODPS という名前のモジュールがありません」というエラーメッセージが表示された場合はどうすればよいですか?

このエラーは、ODPS パッケージを読み込めないことを示しています。読み込みに失敗する理由は次のとおりです。

  • 理由 1:複数の Python バージョンがインストールされています。

    解決策:検索パス(通常は現在のディレクトリ)に、odps.py ファイルまたは init.py ファイルと、odps という名前のディレクトリの両方が含まれていることを確認します。

    • 同じ名前のフォルダーがある場合は、フォルダー名を変更します。

    • 以前に odps という名前の Python パッケージをインストールしたことがある場合は、sudo pip uninstall odps を使用して削除できます。

  • 理由 2:Python 2 と Python 3 の両方のバージョンがインストールされています。

    解決策:デバイスに Python 2 または Python 3 のみがインストールされていることを確認します。

  • 理由 3:現在の Python バージョンで PyODPS がインストールされていません。

    解決策:PyODPS をインストールします。インストール方法については、「PyODPS をインストールする」をご参照ください。

「from odps import ODPS」コードを実行するときに「ODPS という名前をインポートできません」というエラーメッセージが表示された場合はどうすればよいですか?

現在の作業ディレクトリに [odps.py] という名前のファイルがあるかどうかを確認してください。そのようなファイルが存在する場合は、インポート操作を実行する前に名前を変更してください。

「from odps import ODPS」コードを実行するときに「odps モジュールをインポートできません」というエラーメッセージが表示された場合はどうすればよいですか?

このエラーは通常、PyODPS で発生した依存関係の問題が原因で発生します。リンクをクリックして PyODPS テクニカルサポート DingTalk グループに参加し、グループ管理者に連絡して支援を求めてください。

IPython または Jupyter Notebook で PyODPS を使用するときに「ImportError」というエラーメッセージが表示された場合はどうすればよいですか?

コードの先頭に from odps import errors を追加します。

from odps import errors を追加するときにエラーが発生した場合は、Ipython コンポーネントが不足していることを示唆しています。sudo pip install -U jupyter を実行することで、この問題を解決できます。

o.gettable('table_name').size の size フィールドは何を意味しますか?

SIZE フィールドは、テーブルの物理ストレージサイズを示します。

Tunnel エンドポイントを構成するにはどうすればよいですか?

options.tunnel.endpoint を使用して設定を構成できます。詳細については、「aliyun-odps-python-sdk」をご参照ください。

PyODPS で CPython を含むサードパーティパッケージを使用するにはどうすればよいですか?

CPython を含む wheel パッケージを生成することをお勧めします。詳細については、「MaxCompute で使用できる crcmod を作成する」をご参照ください。

PyODPS の DataFrame はどれだけのデータを処理できますか?また、テーブルのサイズに制限はありますか?

PyODPS にはテーブルのサイズに制限はありません。ローカルの Pandas によって作成された DataFrame のサイズは、ローカルメモリのサイズによって制限されます。

DataFrame で max_pt を使用するにはどうすればよいですか?

odps.df.func モジュールを使用して、MaxCompute のビルトイン関数を呼び出します。

from odps.df import func
df = o.get_table('your_table').to_df()
df[df.ds == func.max_pt('your_project.your_table')]  # ds はパーティションフィールドです。     

PyODPS を使用してテーブルにデータを書き込む場合、open_writer() メソッドと write_table() メソッドの違いは何ですか?

write_table() を呼び出すたびに、サーバー上に新しいファイルが作成されます。これは時間がかかり、生成されるファイルが多すぎると、クエリのパフォーマンスが低下し、メモリ不足が発生する可能性があります。これを軽減するために、複数のデータセットを同時に書き込むか、write_table() メソッドで Generator オブジェクトを使用することをお勧めします。write_table() メソッドの使用に関するガイダンスについては、「テーブルにデータを書き込む」をご参照ください。

open_writer() 関数は、デフォルトでブロックに書き込みます。

DataWorks PyODPS ノードでクエリされるデータ量がローカル実行の結果よりも少ないのはなぜですか?

デフォルトでは、DataWorks で Instance Tunnel は有効になっていません。つまり、instance.open_reader は Result インターフェイスを利用します。これは最大 10,000 レコードを取得できます。

Instance Tunnel が有効になると、reader.count を使用してレコード数を取得できます。すべてのデータを反復処理して取得するには、options.tunnel.limit_instance_tunnel = False を設定して制限を削除する必要があります。

DataFrame の実際の件数を取得するにはどうすればよいですか?

  1. PyODPS をインストールした後、Python 環境で次のコマンドを実行して、MaxCompute テーブルを作成し、DataFrame を初期化します。

    iris = DataFrame(o.get_table('pyodps_iris'))        
  2. DataFrame に対して Count 操作を実行し、行の総数を取得します。

    iris.count()      
  3. DataFrame 操作はすぐに実行されず、ユーザーが明示的に Execute メソッドまたは即時実行メソッドを呼び出したときにのみ実行されます。Count メソッドを即座に実行するには、次のコマンドを使用します。

    df.count().execute()    

DataFrames の実際の数を取得する方法については、「集計」をご参照ください。PyODPS メソッドの遅延操作の詳細については、「実行」をご参照ください。

PyODPS を使用するときに「sourceIP がホワイトリストにありません」というエラーメッセージが表示された場合はどうすればよいですか?

PyODPS がアクセスする MaxCompute プロジェクトには、ホワイトリスト保護が適用されています。プロジェクトのオーナーに連絡して、デバイスを IP ホワイトリストに追加してください。IP ホワイトリストの詳細については、「IP アドレスのホワイトリストを管理する」をご参照ください。

from odps import options options.sql.settings を使用して MaxCompute のランタイム環境を構成できない場合はどうすればよいですか?

  • 問題の説明

    PyODPS を使用して SQL を実行する場合、MaxCompute インスタンスを申請する前に、次のコードを使用して MaxCompute ランタイム環境を設定します。

    from odps import options
    options.sql.settings = {'odps.sql.mapper.split.size': 32}     

    タスクを開始した後、6 つのマッパーのみが起動され、設定が適用されていないことが示されました。ただし、クライアントで set odps.stage.mapper.split.size=32 コマンドを実行すると、タスクは 1 分で完了しました。

  • 原因

    クライアントと PyODPS で設定されたパラメーター間に不整合があります。クライアントは odps.stage.mapper.split.size パラメーターを使用しますが、PyODPS は odps.sql.mapper.split.size を使用します。

  • 解決策

    PyODPS のパラメーターを odps.stage.mapper.split.size に変更します。

DataFrame の head メソッドを呼び出すと、「IndexError:listindexoutofrange」というエラーメッセージが表示されるのはなぜですか?

これは、list[index] に要素が含まれていないか、list[index] が許容範囲外であるために発生します。

Pandas DataFrame を MaxCompute にアップロードするときに「ODPSError」というエラーメッセージが表示された場合はどうすればよいですか?

  • 問題の説明

    Pandas DataFrame を MaxCompute にアップロードすると、次のエラーが返されます。

    ODPSError: ODPS entrance should be provided.
  • 原因

    このエラーは、グローバル MaxCompute オブジェクトエントリがないことが原因です。

  • 解決策

    • Room メカニズム %enter を使用すると、グローバルエントリが構成されます。

    • MaxCompute オブジェクトエントリで to_global メソッドを呼び出します。

    • パラメーター DataFrame(pd_df).persist('your_table', odps=odps) を使用します。

DataFrame を使用してテーブルにデータを書き込むときに「lifecycle is not specified in mandatory mode」というエラーメッセージが表示された場合はどうすればよいですか?

  • 問題の説明

    DataFrame を介してテーブルに書き込むときに、次のエラーが返されます。

    table lifecycle is not specified in mandatory mode
  • 原因

    テーブルのライフサイクルが設定されていません。

  • 解決策

    プロジェクトでは各テーブルのライフサイクルを設定する必要があるため、実行するたびに次の情報を設定する必要があります。

    from odps import options
    options.lifecycle = 7  # ライフサイクルの値をここに設定します。ライフサイクルの値は整数(日数)です。

PyODPS を使用してテーブルにデータを書き込むときに「サーバーからのデータストリームが破損している可能性があります」というエラーメッセージが表示された場合はどうすればよいですか?

このエラーは、ダーティデータが原因で発生します。 データ列の数がターゲットテーブルと一致しているかどうかを確認してください。

PyODPS を使用してテーブルからデータを読み取るときに「プロジェクトは保護されています」というエラーメッセージが表示された場合はどうすればよいですか?

プロジェクトのセキュリティポリシーにより、テーブルからのデータの読み取りが禁止されています。すべてのデータを使用するには、次の方法を検討してください。

  • プロジェクトオーナーに連絡して、例外ルールを追加してもらいます。

  • DataWorks またはその他のマスキングツールを使用してデータをマスキングし、保護されていないプロジェクトにエクスポートしてから、データを読み取ります。

データの一部を表示するには、次の方法を使用します。

  • o.execute_sql('select * from <table_name>').open_reader() コマンドを実行して、指定されたテーブルからデータを取得できます。

  • o.get_table('<table_name>').to_df() を使用して、テーブルを DataFrame に変換できます。

PyODPS スクリプトタスクの実行時に「ConnectionError: timed out try catch exception」というエラーメッセージが断続的に表示される場合はどうすればよいですか?

このエラーの考えられる原因は次のとおりです。

  • 接続タイムアウト。 PyODPS のデフォルトのタイムアウトは 5 秒です。次のいずれかのソリューションを使用して、問題に対処します。

    • タイムアウト間隔を増やすには、スクリプトの先頭に次のコードを追加します。

      # 回避策
      from odps import options
      options.connect_timeout=30
    • 例外処理を実装してエラーをキャッチし、再試行を試みます。

  • サンドボックスの制限により、一部のマシンがネットワークにアクセスできない場合があります。タスクを実行し、この問題を解決するには、スケジューリング専用の排他的リソースグループを使用します。

PyODPS を使用して get_sql_task_cost 関数を実行するときに「is not defined」というエラーメッセージが表示された場合はどうすればよいですか。

  • 問題の説明

    PyODPS を使用して get_sql_task_cost 関数を実行すると、次のエラーが返されます。

    NameError: name 'get_task_cost' is not defined.  // NameError: 'get_task_cost' という名前が定義されていません。
  • 解決策

    関数名が正しくありません。

  • 解決策

    get_sql_task_cost の代わりに execute_sql_cost を使用します。

PyODPS を使用してログを表示すると、漢字が自動的にエンコードされた表示に変換されます。ログに漢字を保持するにはどうすればよいですか?

print ("我叫 %s" % ('abc')) と同様の形式でコードを記述して漢字を入力します。これらの問題は Python 2 でのみ発生します。

options.tunnel.use_instance_tunnel = False を設定した場合、MaxCompute でフィールドが DATETIME 型として定義されているのに、SELECT 文を使用して取得したデータが STRING 型になるのはなぜですか?

Open_Reader を呼び出すと、PyODPS はデフォルトで従来の Result インターフェイスを呼び出します。このとき、サーバーから取得されるデータは CSV フォーマットであるため、DATETIME は STRING 型になります。

options.tunnel.use_instance_tunnel = True を設定してインスタンストンネルを有効にすると、PyODPS はデフォルトでインスタンストンネルを使用するようになり、この問題が効果的に解決されます。

豊富な機能を実現するための Python 言語機能の使用方法

  • Python 関数を作成する。

    2 点間の距離を計算するには、ユークリッド距離やマンハッタン距離など、さまざまな方法があります。一連の関数を定義し、計算中に特定の状況に応じて適切な関数を呼び出します。

    def euclidean_distance(from_x, from_y, to_x, to_y):
        return ((from_x - to_x) ** 2 + (from_y - to_y) ** 2).sqrt()
    
    def manhattan_distance(center_x, center_y, x, y):
       return (from_x - to_x).abs() + (from_y - to_y).abs()                      

    次のように呼び出します。

    In [42]: df
         from_x    from_y      to_x      to_y
    0  0.393094  0.427736  0.463035  0.105007
    1  0.629571  0.364047  0.972390  0.081533
    2  0.460626  0.530383  0.443177  0.706774
    3  0.647776  0.192169  0.244621  0.447979
    4  0.846044  0.153819  0.873813  0.257627
    5  0.702269  0.363977  0.440960  0.639756
    6  0.596976  0.978124  0.669283  0.936233
    7  0.376831  0.461660  0.707208  0.216863
    8  0.632239  0.519418  0.881574  0.972641
    9  0.071466  0.294414  0.012949  0.368514
    
    In [43]: euclidean_distance(df.from_x, df.from_y, df.to_x, df.to_y).rename('distance')
       distance
    0  0.330221
    1  0.444229
    2  0.177253
    3  0.477465
    4  0.107458
    5  0.379916
    6  0.083565
    7  0.411187
    8  0.517280
    9  0.094420
    
    In [44]: manhattan_distance(df.from_x, df.from_y, df.to_x, df.to_y).rename('distance')
       distance
    0  0.392670
    1  0.625334
    2  0.193841
    3  0.658966
    4  0.131577
    5  0.537088
    6  0.114198
    7  0.575175
    8  0.702558
    9  0.132617                       
  • Python の条件文とループ文を使用する。

    ユーザーが計算したいテーブルがデータベースに格納されている場合は、構成に従ってテーブルのフィールドを処理し、すべてのテーブルに対して UNION または JOIN 操作を実行する必要があります。 SQL で実装すると非常に複雑になりますが、DataFrame を使用すると非常に簡単に処理できます。

    たとえば、1 つのテーブルに結合する必要があるテーブルが 30 個ある場合、SQL を使用すると、30 個のテーブルに対して UNION ALL 操作を実行する必要があります。 PyODPS を使用する場合、次のコードでタスクを完了できます。

    table_names = ['table1', ..., 'tableN']
    dfs = [o.get_table(tn).to_df() for tn in table_names]
    reduce(lambda x, y: x.union(y), dfs) 
    
    ## reduce 文は次のコードと同等です。
    df = dfs[0]
    for other_df in dfs[1:]:
        df = df.union(other_df)       

Pandas DataFrame バックエンドを使用してローカルの PyODPS プログラムをデバッグするにはどうすればよいですか?

次の 2 つの方法でローカルデバッグを実行します。初期化メソッド以外は、後続のコードは完全に一致します。

  • Pandas DataFrame を介して作成された PyODPS DataFrame は、Pandas を使用してローカル計算を実行できます。

  • MaxCompute テーブルを使用して作成された DataFrame は、MaxCompute で実行できます。

サンプルコードは次のとおりです。

df = o.get_table('movielens_ratings').to_df()
DEBUG = True
if DEBUG:
    df = df[:100].to_pandas(wrap=True)       // Pandas DataFrameに変換

後続のコードがすべて記述されている場合、ローカルテストの速度は非常に高速です。テストが完了したら、デバッグ値を False に変更すると、後続の計算を MaxCompute で実行できます。

MaxCompute Studio を使用してローカルの PyODPS プログラムをデバッグすることをお勧めします。

ネストされたループの実行が遅い場合はどうすればよいですか?

パフォーマンスを最適化するには、各ループの結果を Dict データ構造を使用して取得し、ループの完了後に DataFrame オブジェクトにインポートすることをお勧めします。 DataFrame オブジェクトコード df=XXX を外側のループに配置すると、ループ計算ごとに DataFrame オブジェクトが生成されます。 その結果、ネストされたループの実行速度が遅くなります。

ローカルディレクトリへのデータのダウンロードを回避するにはどうすればよいですか?

詳細については、「PyODPS ノードを使用してローカルディレクトリにデータをダウンロードして処理するか、オンラインでデータを処理する」をご参照ください。

どのようなシナリオで PyODPS データをオンプレミス マシンにダウンロードして処理できますか?

PyODPS データは、以下の状況でローカル処理のためにダウンロードできます。

  • データ ボリュームが少ない場合は、ローカル データ処理を実行します。

  • 1 行が複数行になる操作や、Python 関数をデータの単一行に適用する操作の場合は、PyODPS DataFrame を使用して MaxCompute の並列計算能力を効果的に活用します。

    たとえば、JSON 文字列データをキーと値のペアに基づいて行に展開するには、次のコードを使用します。

    In [12]: df
                   json
    0  {"a": 1, "b": 2}
    1  {"c": 4, "b": 3}
    
    In [14]: from odps.df import output
    
    In [16]: @output(['k', 'v'], ['string', 'int'])
        ...: def h(row):  # 関数 h を定義
        ...:     import json
        ...:     for k, v in json.loads(row.json).items():  # json データを展開
        ...:         yield k, v  # キーと値を返す
        ...:   
    
    In [21]: df.apply(h, axis=1)  # 関数 h を各行に適用
       k  v
    0  a  1
    1  b  2
    2  c  4
    3  b  3                          

open_reader を使用して取得できるレコードは最大 10,000 件です。10,000 件を超えるレコードを取得するにはどうすればよいですか?

create table as select ... を使用して SQL の結果をテーブルとして保存し、table.open_reader で読み取ることができます。

組み込み演算子を使用することが推奨されるのはなぜですか?

UDF は、計算中に組み込み演算子よりも実行速度が遅くなります。そのため、組み込み演算子を使用することをお勧めします。

数百万行のデータを処理する必要があり、行ごとに UDF を使用する場合は、実行時間が 7 秒から 27 秒に増加します。より大きなデータセットまたはより複雑な操作が必要な場合は、時間の差がさらに大きくなる可能性があります。

DataFrame().schema.partitions を使用して取得したパーティションテーブルのパーティション値が Empty なのはなぜですか?

DataFrame は、パーティションフィールドと通常のフィールドを区別しないため、パーティションテーブルのパーティションフィールドは通常のフィールドとして扱われます。次のようにパーティションフィールドを除外します。

df = o.get_table().to_df()
print(df[df.ds == ''].execute()) # パーティションフィールドを除外して実行

パーティションの設定方法、またはパーティションからのデータの読み取り方法の詳細については、「テーブル」をご参照ください。

PyODPS DataFrame を使用してデカルト積演算を実行するにはどうすればよいですか?

詳細については、「PyODPS DataFrame でのデカルト積の処理」をご参照ください。

Jieba に基づいて PyODPS ノードを使用して中国語テキストをセグメント化するにはどうすればよいですか。

詳細については、「PyODPS ノードを使用して Jieba に基づいて中国語テキストをセグメント化する」をご参照ください。

PyODPS を使用して完全データ をダウンロードするにはどうすればよいですか?

デフォルトでは、PyODPS はインスタンスから読み取ることができるデータ量を制限しません。ただし、Tunnel コマンドを使用して保護されたプロジェクト用にダウンロードできるデータ量は制限されています。options.tunnel.limit_instance_tunnel を指定しない場合、制限は自動的に有効になり、ダウンロードできるデータレコード数は MaxCompute プロジェクトの構成に基づいて制限されます。ほとんどの場合、一度に最大 10,000 件のデータレコードをダウンロードできます。すべてのデータを反復的に取得する必要がある場合は、データ量の limit を無効にする必要があります。Instance Tunnel を有効にし、limit を無効にするには、次の文を実行します。

options.tunnel.use_instance_tunnel = True
options.tunnel.limit_instance_tunnel = False  # 全てのデータを読み取るための制限を無効にします。

with instance.open_reader() as reader:
    # 全てのデータは Instance Tunnel を介して読み取ることができます。

execute_sql または DataFrame を使用して、フィールドの null 値の割合を計算できますか?

集約パフォーマンスが高いため、DataFrame を使用して集約操作を実行することをお勧めします。

PyODPS のデータ型を構成する方法

PyODPS で新しいデータ型を有効にするには、次の手順に従います。

  • execute_sql メソッドで新しいデータ型を有効にすることで、o.execute_sql('set odps.sql.type.system.odps2=true;query_sql', hints={"odps.sql.submit.mode" : "script"}) を実行できます。

  • DataFrame を介して新しいデータ型を有効にするには (persist、execute、to_pandas など)、hints パラメーターを使用して設定します。図示されている設定方法は、単一のジョブに対してのみ有効です。

    from odps.df import DataFrame
    users - DataFrame(o.get_table('odps2_test'))
    users.persist('copy_test',hints={'odps.sql.type.system.odps2':'true'}) # odps2 型システムを有効にする
    

    DataFrame を使用する際に、グローバルな効果が必要な場合は、オプション パラメーター options.sql.use_odps2_extension = True を設定します。

PyODPS の使用時にエラーメッセージ「ValueError」が表示された場合はどうすればよいですか。

この問題は、次の方法で解決できます。

  • SDK をバージョン V0.8.4 以降にアップグレードします。

  • SQL に次の文を追加します。

    from odps.types import Decimal
    # Decimal 型の最大精度を 38 に設定します。
    Decimal._max_precision=38

PyODPS 経由で SQL を実行すると遅い場合のトラブルシューティング方法

SQL タスクの実行が遅い場合、多くの場合 PyODPS には関連していません。次の手順を使用してトラブルシューティングを行ってください。

  1. ネットワークとサーバーの待機時間を確認する

    • タスクの送信に使用されるプロキシサーバーまたはネットワークリンクに遅延があるかどうかを確認します。

    • サーバーのタスクキューに遅延があるかどうかを確認します。

  2. データ読み取り効率を評価する

    SQL の実行に大量のデータの読み取りが含まれる場合、データサイズが大きすぎること、またはデータシャードが多すぎるために読み取り速度が低下していないかを確認します。次の手順で進めることができます。

    まず、タスクの送信とデータの読み取りを分離することを検討してください。run_sql を使用してタスクを送信し、instance.wait_for_success を使用して完了を待ちます。その後、instance.open_reader を使用してデータを読み取ります。これにより、各操作で発生する遅延を特定できます。分割前後の例を以下に示します。

    • 分割前:

      with o.execute_sql('select * from your_table').open_reader() as reader:
          for row in reader:
              print(row)
    • 分割後:

      inst = o.run_sql('select * from your_table')
      inst.wait_for_success()
      with inst.open_reader() as reader:
          for row in reader:
              print(row)
  3. DataWorks ジョブのステータスを確認する (該当する場合)

    DataWorks で送信されたジョブの場合、特に PyODPS のバージョンが 0.11.6 より前の場合、正しく送信されたにもかかわらず Logview を生成できない SQL タスクがあるかどうかを確認します。これらのタスクは通常、execute_sql メソッドまたは run_sql メソッドを使用します。

  4. ローカル環境要因分析

    問題がローカル環境に関連しているかどうかを確認するには、デバッグログ機能を有効にすることをお勧めします。PyODPS はすべてのリクエストとレスポンスを記録するため、ログを調べて遅延の原因を特定できます。

    以下に例を示します。

    import datetime
    import logging
    from odps import ODPS
    
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    o = ODPS(...)  # アカウント情報を入力します。環境に MaxCompute Entry が提供されている場合は、無視してください。
    # ローカル時間を表示して、ローカル操作が開始された時刻を確認します
    print("Check time:", datetime.datetime.now())
    # タスクを送信する
    inst = o.run_sql("select * from your_table")

    標準出力は、ここに示す結果のようになります。

    Check time: 2025-01-24 15:34:21.531330
    2025-01-24 15:34:21,532 - odps.rest - DEBUG - Start request.
    2025-01-24 15:34:21,532 - odps.rest - DEBUG - POST: http://service.<region>.maxcompute.aliyun.com/api/projects/<project>/instances
    2025-01-24 15:34:21,532 - odps.rest - DEBUG - data: b'<?xml version="1.0" encoding="utf-8"?>\n<Instance>\n  <Job>\n    <Priority>9</Priority>\n    <Tasks>\n      <SQL>\n        ....
    2025-01-24 15:34:21,532 - odps.rest - DEBUG - headers: {'Content-Type': 'application/xml'}
    2025-01-24 15:34:21,533 - odps.rest - DEBUG - request url + params /api/projects/<project>/instances?curr_project=<project>
    2025-01-24 15:34:21,533 - odps.accounts - DEBUG - headers before signing: {'Content-Type': 'application/xml', 'User-Agent': 'pyodps/0.12.2 CPython/3.7.12', 'Content-Length': '736'}
    2025-01-24 15:34:21,533 - odps.accounts - DEBUG - headers to sign: OrderedDict([('content-md5', ''), ('content-type', 'application/xml'), ('date', 'Fri, 24 Jan 2025 07:34:21 GMT')])
    2025-01-24 15:34:21,533 - odps.accounts - DEBUG - canonical string: POST
    
    application/xml
    Fri, 24 Jan 2025 07:34:21 GMT
    /projects/maxframe_ci_cd/instances?curr_project=maxframe_ci_cd
    2025-01-24 15:34:21,533 - odps.accounts - DEBUG - headers after signing: {'Content-Type': 'application/xml', 'User-Agent': 'pyodps/0.12.2 CPython/3.7.12', 'Content-Length': '736', ....
    2025-01-24 15:34:21,533 - urllib3.connectionpool - DEBUG - Resetting dropped connection: service.<region>.maxcompute.aliyun.com
    2025-01-24 15:34:22,027 - urllib3.connectionpool - DEBUG - http://service.<region>.maxcompute.aliyun.com:80 "POST /api/projects/<project>/instances?curr_project=<project> HTTP/1.1" 201 0
    2025-01-24 15:34:22,027 - odps.rest - DEBUG - response.status_code 201
    2025-01-24 15:34:22,027 - odps.rest - DEBUG - response.headers:
    {'Server': '<Server>', 'Date': 'Fri, 24 Jan 2025 07:34:22 GMT', 'Content-Type': 'text/plain;charset=utf-8', 'Content-Length': '0', 'Connection': 'close', 'Location': ....
    2025-01-24 15:34:22,027 - odps.rest - DEBUG - response.content: b''

    この出力は、コードがタスクを開始した時刻 (2025-01-24 15:34:21.531)、リクエストを送信した時刻 (2025-01-24 15:34:21.533)、およびサーバーのレスポンスを受信した時刻 (2025-01-24 15:34:22.027) を示しており、各ステージの期間を明確にしています。