全部产品
Search
文档中心

MaxCompute:FAQ PyODPS

更新时间:Jul 06, 2025

Topik ini menjelaskan pertanyaan-pertanyaan yang sering diajukan saat menggunakan PyODPS.

Kategori Masalah

Pertanyaan yang Sering Diajukan (FAQ)

Instalasi PyODPS

Mengimpor modul

Menggunakan PyODPS

Apa yang harus saya lakukan jika pesan kesalahan "Warning: XXX not installed" muncul saat saya menginstal PyODPS?

Masalah ini terjadi karena komponen yang hilang. Identifikasi nama komponen dari informasi XXX dalam pesan kesalahan, lalu instal menggunakan perintah pip.

Apa yang harus saya lakukan jika pesan kesalahan "Project Not Found" muncul saat saya menginstal PyODPS?

Penyebab masalah ini adalah:

  • Konfigurasi Endpoint salah dan harus dimodifikasi ke Endpoint proyek target. Untuk informasi lebih lanjut tentang endpoint, lihat Endpoints.

  • Posisi parameter objek entri MaxCompute tidak valid. Pastikan itu diisi dengan benar. Untuk informasi lebih lanjut tentang parameter objek entri MaxCompute, lihat Migrasikan node PyODPS dari DataWorks ke lingkungan lokal.

Apa yang harus saya lakukan jika pesan kesalahan "Syntax Error" muncul saat saya menginstal PyODPS?

Kesalahan ini disebabkan oleh versi Python yang tidak didukung. Python 2.5 atau lebih awal tidak didukung oleh PyODPS. Gunakan versi utama yang didukung oleh PyODPS, seperti Python 2.7.6 atau versi minor terbaru, Python 3.3 atau versi minor terbaru, dan Python 2.6.

Apa yang harus saya lakukan jika pesan kesalahan "Permission Denied" muncul saat saya menginstal PyODPS di macOS?

Untuk menginstal PyODPS, gunakan perintah sudo pip install pyodps.

Apa yang harus saya lakukan jika pesan kesalahan "Operation Not Permitted" muncul saat saya menginstal PyODPS di macOS?

Kesalahan ini terjadi karena System Integrity Protection (SIP). Untuk menyelesaikannya, restart perangkat Anda dan tekan + R selama proses boot. Setelah itu, jalankan perintah berikut di terminal.

csrutil disable
reboot       

Untuk informasi lebih lanjut, lihat Operation Not Permitted when on root - El Capitan (rootless disabled).

Apa yang harus saya lakukan jika pesan kesalahan "No Module Named ODPS" muncul saat saya menjalankan kode from odps import ODPS?

Kesalahan ini menunjukkan bahwa paket ODPS tidak dapat dimuat. Penyebab yang mungkin adalah sebagai berikut:

  • Alasan 1: Beberapa versi Python diinstal.

    Solusi: Pastikan jalur pencarian, yang biasanya merupakan direktori saat ini, mencakup file odps.py atau init.py dan direktori bernama odps.

    • Jika itu adalah folder dengan nama yang sama, ubah nama foldernya.

    • Jika Anda sebelumnya telah menginstal paket Python bernama odps, Anda dapat menghapusnya menggunakan sudo pip uninstall odps.

  • Alasan 2: Versi Python 2 dan Python 3 diinstal.

    Solusi: Pastikan hanya Python 2 atau Python 3 yang diinstal di perangkat.

  • Alasan 3: PyODPS tidak diinstal di bawah versi Python saat ini.

    Solusi: Instal PyODPS. Untuk metode instalasi, lihat Instal PyODPS.

Apa yang harus saya lakukan jika pesan kesalahan "Cannot Import Name ODPS" muncul saat saya menjalankan kode "from odps import ODPS"?

Silakan periksa keberadaan file bernama odps.py di direktori kerja saat ini. Jika file tersebut ada, ubah namanya sebelum melakukan operasi impor.

Apa yang harus saya lakukan jika pesan kesalahan "Cannot Import Module odps" muncul saat saya menjalankan kode "from odps import ODPS"?

Kesalahan ini biasanya disebabkan oleh masalah dependensi yang dihadapi PyODPS. Klik tautan untuk bergabung dengan grup dukungan teknis PyODPS di DingTalk dan hubungi administrator grup untuk bantuan.

Apa yang harus saya lakukan jika pesan kesalahan "ImportError" muncul saat saya menggunakan PyODPS di IPython atau Jupyter Notebook?

Di awal kode, tambahkan from odps import errors. Jika kesalahan masih ada, dependensi Ipython mungkin hilang. Anda dapat menyelesaikan masalah ini dengan menjalankan sudo pip install -U jupyter.

Apa arti bidang size dalam o.gettable('table_name').size?

Bidang SIZE menunjukkan ukuran penyimpanan fisik tabel.

Bagaimana cara mengonfigurasi Titik akhir Tunnel?

Anda dapat mengonfigurasi pengaturan menggunakan options.tunnel.endpoint. Untuk informasi lebih lanjut, lihat aliyun-odps-python-sdk.

Bagaimana cara menggunakan paket pihak ketiga yang berisi CPython di PyODPS?

Kami merekomendasikan agar Anda membuat paket wheel yang berisi CPython. Untuk informasi lebih lanjut, lihat Buat crcmod yang dapat digunakan di MaxCompute.

Berapa banyak data yang dapat ditangani oleh DataFrame di PyODPS, dan apakah ada batasan pada ukuran tabel?

PyODPS tidak memiliki batasan pada ukuran tabel. Ukuran DataFrame yang dibuat oleh Pandas lokal dibatasi oleh ukuran memori lokal.

Bagaimana cara menggunakan max_pt dalam DataFrame?

Gunakan modul odps.df.func untuk memanggil fungsi bawaan 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 adalah bidang partisi.     

Apa perbedaan antara metode open_writer() dan write_table() saat Anda menggunakan PyODPS untuk menulis data ke tabel?

Setiap pemanggilan write_table() menghasilkan pembuatan file baru di server, yang bisa memakan waktu dan dapat menyebabkan penurunan kinerja query serta potensi kekurangan memori jika terlalu banyak file yang dihasilkan. Untuk mengurangi hal ini, kami sarankan Anda menulis beberapa dataset secara bersamaan atau menggunakan objek Generator dengan metode write_table(). Untuk panduan menggunakan metode write_table(), lihat Tulis data ke tabel.

Fungsi open_writer() menulis ke Block secara default.

Mengapa jumlah data yang diquery pada node PyODPS DataWorks lebih sedikit daripada hasil eksekusi lokal?

Secara default, Instance Tunnel tidak diaktifkan di DataWorks, artinya instance.open_reader menggunakan antarmuka Result, yang mampu mengambil maksimal 10.000 rekaman.

Setelah Instance Tunnel diaktifkan, Anda dapat mengambil jumlah rekaman dengan menggunakan reader.count. Untuk melakukan iterasi dan mengambil semua data, Anda harus menghapus batasan limit dengan menyetel options.tunnel.limit_instance_tunnel = False.

Bagaimana cara mendapatkan jumlah hitungan sebenarnya dalam DataFrame?

  1. Setelah menginstal PyODPS, jalankan perintah berikut di lingkungan Python untuk membuat tabel MaxCompute dan menginisialisasi DataFrame.

    iris = DataFrame(o.get_table('pyodps_iris'))        
  2. Lakukan operasi Count pada DataFrame untuk mendapatkan total jumlah baris.

    iris.count()      
  3. Karena operasi DataFrame tidak dieksekusi segera, mereka hanya dieksekusi ketika pengguna secara eksplisit memanggil metode Execute atau metode eksekusi langsung. Untuk memastikan metode Count dieksekusi dengan cepat, gunakan perintah berikut.

    df.count().execute()    

Untuk metode mendapatkan jumlah sebenarnya dari DataFrame, lihat Aggregasi. Untuk detail tentang operasi penundaan metode PyODPS, lihat Eksekusi.

Apa yang harus saya lakukan jika pesan kesalahan "sourceIP is not in the white list" muncul saat saya menggunakan PyODPS?

Proyek MaxCompute yang diakses oleh PyODPS memiliki perlindungan daftar putih. Hubungi pemilik proyek untuk menambahkan perangkat Anda ke daftar putih IP. Untuk informasi lebih lanjut tentang informasi daftar putih IP, lihat Kelola daftar putih alamat IP.

Apa yang harus saya lakukan jika gagal mengonfigurasi lingkungan runtime MaxCompute dengan menggunakan "from odps import options options.sql.settings"?

  • Deskripsi masalah

    Saat menjalankan SQL menggunakan PyODPS, atur lingkungan runtime MaxCompute melalui kode berikut sebelum mengajukan instance MaxCompute.

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

    Setelah memulai tugas, hanya 6 Mapper yang diluncurkan, menunjukkan bahwa pengaturan tersebut tidak diterapkan. Namun, ketika perintah set odps.stage.mapper.split.size=32 dijalankan di klien, tugas selesai dalam satu menit.

  • Penyebab

    Ada ketidaksesuaian antara parameter yang ditetapkan di klien dan PyODPS. Klien menggunakan parameter odps.stage.mapper.split.size, sedangkan PyODPS menggunakan odps.sql.mapper.split.size.

  • Solusi

    Ubah parameter di PyODPS menjadi odps.stage.mapper.split.size.

Mengapa pesan kesalahan "IndexError:listindexoutofrange" muncul saat saya memanggil metode head dari DataFrame?

Ini terjadi karena list[index] tidak berisi elemen atau list[index] berada di luar rentang yang diizinkan.

Apa yang harus saya lakukan jika pesan kesalahan "ODPSError" muncul saat saya mengunggah Pandas DataFrame ke MaxCompute?

  • Deskripsi masalah

    Saat mengunggah Pandas DataFrame ke MaxCompute, kesalahan berikut dikembalikan.

    ODPSError: ODPS entrance should be provided.
  • Penyebab

    Kesalahan ini disebabkan oleh tidak adanya objek entri MaxCompute global.

  • Solusi

    • Saat Anda menggunakan mekanisme Room %enter, itu mengonfigurasi entri global.

    • Panggil metode to_global pada objek entri MaxCompute.

    • Gunakan parameter DataFrame(pd_df).persist('your_table', odps=odps).

Apa yang harus saya lakukan jika pesan kesalahan "lifecycle is not specified in mandatory mode" muncul saat saya menggunakan DataFrame untuk menulis data ke tabel?

  • Deskripsi masalah

    Saat menulis tabel melalui DataFrame, kesalahan berikut dikembalikan.

    table lifecycle is not specified in mandatory mode
  • Penyebab

    Lifecycle tabel tidak diatur.

  • Solusi

    Proyek memerlukan pengaturan lifecycle untuk setiap tabel, jadi Anda harus menyetel informasi berikut setiap kali Anda mengeksekusi.

    from odps import options
    options.lifecycle = 7  # Atur nilai lifecycle di sini. Nilai lifecycle adalah bilangan bulat, dalam hari.      

Apa yang harus saya lakukan jika pesan kesalahan "Perhaps the datastream from server is crushed" muncul saat saya menggunakan PyODPS untuk menulis data ke tabel?

Kesalahan ini disebabkan oleh data kotor. Periksa apakah jumlah kolom data konsisten dengan tabel target.

Apa yang harus saya lakukan jika pesan kesalahan "Project is protected" muncul saat saya menggunakan PyODPS untuk membaca data dari tabel?

Kebijakan keamanan pada proyek melarang membaca data dari tabel. Untuk menggunakan semua data, pertimbangkan metode berikut:

  • Hubungi pemilik proyek untuk menambahkan aturan pengecualian.

  • Gunakan DataWorks atau alat masking lainnya untuk menyamarkan data, ekspor ke proyek yang tidak dilindungi, lalu baca.

Untuk melihat sebagian data, gunakan metode berikut:

  • Anda dapat menjalankan perintah o.execute_sql('select * from <table_name>').open_reader() untuk mengambil data dari tabel tertentu.

  • Anda dapat mengonversi tabel ke DataFrame menggunakan o.get_table('<table_name>').to_df().

Apa yang harus saya lakukan jika pesan kesalahan "ConnectionError: timed out try catch exception" kadang-kadang muncul saat saya menjalankan tugas skrip PyODPS?

Penyebab potensial dari kesalahan ini adalah:

  • Timeout koneksi. Timeout default untuk PyODPS adalah 5 detik. Gunakan salah satu solusi berikut untuk mengatasi masalah ini:

    • Untuk meningkatkan interval timeout, tambahkan kode berikut di awal skrip Anda:

      # workaround
      from odps import options
      options.connect_timeout=30
    • Implementasikan penanganan pengecualian untuk menangkap kesalahan dan mencoba ulang.

  • Pembatasan sandbox mungkin mencegah beberapa mesin mengakses jaringan. Gunakan grup sumber daya eksklusif untuk penjadwalan untuk mengeksekusi tugas dan menyelesaikan masalah ini.

Apa yang harus saya lakukan jika pesan kesalahan "is not defined" muncul saat saya menggunakan PyODPS untuk menjalankan fungsi get_sql_task_cost?

  • Deskripsi masalah

    Saat menjalankan fungsi get_sql_task_cost menggunakan PyODPS, kesalahan berikut dikembalikan.

    NameError: name 'get_task_cost' is not defined.
  • Solusi

    Nama fungsi tidak valid.

  • Solusi

    Gunakan execute_sql_cost sebagai ganti get_sql_task_cost.

Saat saya menggunakan PyODPS untuk menampilkan log, karakter Cina secara otomatis dikonversi menjadi tampilan terenkripsi. Bagaimana cara mempertahankan karakter Cina dalam log?

Masukkan karakter Cina dengan menulis kode dalam format serupa dengan print ("我叫 %s" % ('abc')). Masalah ini hanya terjadi di Python 2.

Saat menyetel options.tunnel.use_instance_tunnel = False, mengapa bidang yang didefinisikan sebagai tipe DATETIME di MaxCompute, tetapi data yang diperoleh menggunakan pernyataan SELECT adalah tipe STRING?

Saat memanggil Open_Reader, PyODPS akan memanggil antarmuka Result warisan secara default. Pada saat ini, data yang diperoleh dari server berada dalam format CSV, sehingga DATETIME adalah tipe STRING.

Saat Instance Tunnel diaktifkan dengan menyetel options.tunnel.use_instance_tunnel = True, PyODPS secara default menggunakan Instance Tunnel, secara efektif menyelesaikan masalah ini.

Bagaimana cara menggunakan fitur bahasa Python untuk mencapai fungsionalitas yang kaya?

  • Tulis fungsi Python.

    Ada berbagai metode untuk menghitung jarak antara dua titik, seperti Jarak Euclidean dan Jarak Manhattan. Definisikan serangkaian fungsi dan panggil fungsi yang sesuai sesuai situasi selama perhitungan.

    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(from_x, from_y, to_x, to_y):
       return (from_x - to_x).abs() + (from_y - to_y).abs()                      

    Panggil sebagai berikut.

    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                       
  • Manfaatkan pernyataan kondisional dan loop dalam Python.

    Jika tabel yang ingin dihitung pengguna disimpan dalam database, perlu memproses bidang tabel sesuai konfigurasi, lalu melakukan operasi UNION atau JOIN pada semua tabel. Jika diimplementasikan dengan SQL, cukup kompleks, tetapi sangat sederhana diproses dengan DataFrame.

    Sebagai contoh, jika Anda memiliki 30 tabel yang perlu digabungkan menjadi satu tabel, jika Anda menggunakan SQL, Anda perlu melakukan operasi UNION ALL pada 30 tabel. Jika Anda menggunakan PyODPS, kode berikut dapat menyelesaikan tugas.

    table_names = ['table1', ..., 'tableN']
    dfs = [o.get_table(tn).to_df() for tn in table_names]
    reduce(lambda x, y: x.union(y), dfs) 
    
    ## Pernyataan reduce setara dengan kode berikut.
    df = dfs[0]
    for other_df in dfs[1:]:
        df = df.union(other_df)       

Bagaimana cara menggunakan backend Pandas DataFrame untuk men-debug program PyODPS lokal?

Lakukan debugging lokal dengan dua cara berikut. Selain metode inisialisasi, kode berikutnya sepenuhnya konsisten:

  • DataFrame PyODPS yang dibuat melalui Pandas DataFrame dapat menggunakan Pandas untuk melakukan perhitungan lokal.

  • DataFrame yang dibuat menggunakan tabel MaxCompute dapat dieksekusi di MaxCompute.

Kode sampel adalah sebagai berikut.

df = o.get_table('movielens_ratings').to_df()
DEBUG = True
if DEBUG:
    df = df[:100].to_pandas(wrap=True)       

Saat semua kode berikutnya ditulis, kecepatan pengujian lokal sangat cepat. Setelah pengujian selesai, Anda dapat mengubah nilai Debug menjadi False, sehingga perhitungan berikutnya dapat dieksekusi di MaxCompute.

Kami merekomendasikan agar Anda menggunakan MaxCompute Studio untuk men-debug program PyODPS lokal.

Apa yang harus saya lakukan jika eksekusi loop bersarang lambat?

Untuk mengoptimalkan kinerja, kami sarankan Anda mendapatkan hasil setiap loop menggunakan struktur data Dict dan kemudian mengimpornya ke objek DataFrame setelah loop selesai. Jika Anda menempatkan kode objek DataFrame df=XXX di loop luar, objek DataFrame dihasilkan untuk setiap perhitungan loop. Akibatnya, kecepatan eksekusi loop bersarang lambat.

Bagaimana cara mencegah pengunduhan data ke direktori lokal?

Untuk informasi lebih lanjut, lihat Gunakan node PyODPS untuk mengunduh data ke direktori lokal untuk pemrosesan atau untuk memproses data secara online.

Dalam skenario apa saya dapat mengunduh data PyODPS ke mesin lokal saya untuk memproses data?

Data PyODPS dapat diunduh untuk pemrosesan lokal dalam situasi berikut:

  • Volume data kecil.

  • Untuk operasi di mana satu baris menjadi beberapa baris atau menerapkan fungsi Python ke baris data tunggal, gunakan PyODPS DataFrame untuk memanfaatkan daya komputasi paralel MaxCompute secara efektif.

    Sebagai contoh, untuk memperluas string JSON menjadi baris berdasarkan pasangan Key-Value, gunakan kode berikut:

    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):
        ...:     import json
        ...:     for k, v in json.loads(row.json).items():
        ...:         yield k, v
        ...:   
    
    In [21]: df.apply(h, axis=1)
       k  v
    0  a  1
    1  b  2
    2  c  4
    3  b  3                          

Sebanyak 10.000 rekaman dapat diperoleh dengan menggunakan open_reader. Bagaimana cara mendapatkan lebih dari 10.000 rekaman?

Anda dapat menyimpan hasil SQL sebagai tabel menggunakan create table as select ..., lalu membacanya dengan table.open_reader.

Mengapa saya disarankan untuk menggunakan operator bawaan alih-alih UDF?

UDF dieksekusi lebih lambat daripada operator bawaan selama perhitungan. Oleh karena itu, kami sarankan Anda menggunakan operator bawaan.

Jika Anda perlu memproses jutaan baris data dan Anda menggunakan UDF untuk satu baris, waktu eksekusi bertambah dari 7 detik menjadi 27 detik. Jika dataset yang lebih besar atau operasi yang lebih kompleks diperlukan, celah waktu mungkin lebih besar.

Mengapa nilai partisi tabel terpartisi yang diperoleh melalui DataFrame().schema.partitions kosong?

DataFrame tidak membedakan antara bidang partisi dan bidang biasa, sehingga bidang partisi tabel terpartisi diperlakukan sebagai bidang biasa. Filter bidang partisi sebagai berikut:

df = o.get_table().to_df()
print(df[df.ds == ''].execute())

Untuk informasi lebih lanjut tentang cara mengonfigurasi partisi atau membaca data dari partisi, lihat Tabel.

Bagaimana cara menggunakan PyODPS DataFrame untuk melakukan operasi Produk Kartesius?

Untuk informasi lebih lanjut, lihat PyODPS DataFrame Menangani Produk Kartesius.

Bagaimana cara menggunakan node PyODPS untuk membagi teks Cina berdasarkan Jieba?

Untuk informasi lebih lanjut, lihat Gunakan node PyODPS untuk membagi teks Cina berdasarkan Jieba.

Bagaimana cara menggunakan PyODPS untuk mengunduh data lengkap?

Secara default, PyODPS tidak membatasi jumlah data yang dapat dibaca dari instance. Namun, jumlah data yang dapat diunduh untuk proyek yang dilindungi dengan menggunakan perintah Tunnel dibatasi. Jika Anda tidak menentukan options.tunnel.limit_instance_tunnel, batasan otomatis diaktifkan, dan jumlah rekaman data yang dapat diunduh dibatasi berdasarkan konfigurasi proyek MaxCompute. Dalam kebanyakan kasus, maksimal 10.000 rekaman data dapat diunduh sekaligus. Jika Anda perlu mendapatkan semua data secara iteratif, Anda harus menonaktifkan limit pada jumlah data. Anda dapat menjalankan pernyataan berikut untuk mengaktifkan Instance Tunnel dan menonaktifkan limit:

options.tunnel.use_instance_tunnel = True
options.tunnel.limit_instance_tunnel = False  # Nonaktifkan batasan untuk membaca semua data.

with instance.open_reader() as reader:
    # Semua data dapat dibaca melalui Instance Tunnel.

Bisakah saya menggunakan execute_sql atau DataFrame untuk menghitung persentase nilai null dari suatu bidang?

Kami merekomendasikan agar Anda menggunakan DataFrame untuk melakukan operasi agregat karena kinerja agregatnya yang tinggi.

Bagaimana cara mengonfigurasi tipe data untuk PyODPS?

Aktifkan tipe data baru di PyODPS sebagai berikut:

  • Dengan mengaktifkan tipe data baru dengan metode execute_sql, Anda dapat menjalankan o.execute_sql('set odps.sql.type.system.odps2=true;query_sql', hints={"odps.sql.submit.mode" : "script"}).

  • Untuk mengaktifkan tipe data baru melalui DataFrame, seperti persist, execute, atau to_pandas, atur melalui parameter hints. Metode pengaturan yang diilustrasikan hanya efektif untuk satu pekerjaan.

    from odps.df import DataFrame
    users = DataFrame(o.get_table('odps2_test'))
    users.persist('copy_test',hints={'odps.sql.type.system.odps2':'true'})

    Saat menggunakan DataFrame, jika Anda memerlukan efek global, atur parameter Option options.sql.use_odps2_extension = True.

Apa yang harus saya lakukan jika pesan kesalahan "ValueError" muncul saat saya menggunakan PyODPS?

Selesaikan masalah ini dengan cara berikut:

  • Tingkatkan SDK ke versi V0.8.4 atau lebih baru.

  • Tambahkan pernyataan berikut dalam SQL:

    from odps.types import Decimal
    Decimal._max_precision=38

Bagaimana cara menyelesaikan masalah bahwa kecepatan menjalankan pernyataan SQL melalui PyODPS lambat?

Jika tugas SQL dieksekusi dengan lambat, seringkali tidak terkait dengan PyODPS. Lakukan pemecahan masalah menggunakan langkah-langkah berikut:

  1. Periksa latensi jaringan dan server

    • Verifikasi apakah ada penundaan di server proxy atau tautan jaringan yang digunakan untuk mengirimkan tugas.

    • Tentukan apakah ada penundaan di antrian tugas server.

  2. Evaluasi efisiensi pembacaan data

    Jika eksekusi SQL Anda melibatkan pembacaan volume data yang besar, periksa apakah kecepatan pembacaan berkurang karena ukuran data yang terlalu besar atau jumlah shard data yang berlebihan. Berikut cara Anda dapat melanjutkan:

    Pertama, pertimbangkan untuk memisahkan pengiriman tugas dari pembacaan data. Gunakan run_sql untuk mengirimkan tugas, lalu instance.wait_for_success untuk menunggu hingga selesai. Setelah itu, baca data dengan instance.open_reader. Ini akan membantu Anda mengidentifikasi penundaan yang disebabkan oleh setiap operasi. Lihat contoh berikut sebelum dan sesudah pemisahan:

    • Sebelum pemisahan:

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

      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. Verifikasi status pekerjaan DataWorks (Jika Berlaku)

    Untuk pekerjaan yang dikirimkan di DataWorks, pastikan apakah ada tugas SQL yang telah dikirimkan dengan benar tetapi gagal menghasilkan Logview, terutama ketika versi PyODPS di bawah 0.11.6. Tugas-tugas ini biasanya menggunakan metode execute_sql atau run_sql.

  4. Analisis faktor lingkungan lokal

    Untuk menentukan apakah masalah tersebut terkait dengan lingkungan lokal, mengaktifkan fungsi log debug direkomendasikan. PyODPS akan mencatat semua permintaan dan respons, memungkinkan Anda untuk menemukan sumber penundaan dengan memeriksa log.

    Berikut adalah contohnya:

    import datetime
    import logging
    from odps import ODPS
    
    logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    o = ODPS(...)  # Isi akun di sini. Jika lingkungan telah menyediakan MaxCompute Entry, abaikan.
    # Cetak waktu lokal untuk menentukan kapan operasi lokal dimulai
    print("Periksa waktu:", datetime.datetime.now())
    # Kirim tugas
    inst = o.run_sql("select * from your_table")

    Keluaran standar Anda harus menyerupai hasil yang ditunjukkan di sini:

    Periksa waktu: 2025-01-24 15:34:21.531330
    2025-01-24 15:34:21,532 - odps.rest - DEBUG - Mulai permintaan.
    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 - url permintaan + params /api/projects/<project>/instances?curr_project=<project>
    2025-01-24 15:34:21,533 - odps.accounts - DEBUG - headers sebelum penandatanganan: {'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 untuk ditandatangani: 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 - string kanonikal: 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 setelah penandatanganan: {'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 - Mengatur ulang koneksi yang terputus: 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''

    Keluaran ini mengungkapkan waktu saat kode memulai tugas (2025-01-24 15:34:21.531), mengirimkan permintaan (2025-01-24 15:34:21.533), dan menerima respons server (2025-01-24 15:34:22.027), sehingga memperjelas durasi setiap tahap.