Pelajari cara membuat, membaca, dan menulis tabel eksternal untuk data CSV dan TSV yang disimpan di Object Storage Service (OSS).
Catatan penggunaan
Tabel eksternal OSS tidak mendukung properti cluster.
Ukuran satu file tidak boleh melebihi 2 GB. Anda harus membagi file yang berukuran lebih dari 2 GB.
MaxCompute dan OSS harus berada di wilayah yang sama.
Tipe data yang didukung
Untuk informasi selengkapnya mengenai tipe data MaxCompute, lihat Data Type Version 1.0 dan Data Type Version 2.0.
Untuk informasi selengkapnya mengenai SmartParse, lihat Kompatibilitas tipe fleksibel Smart Parse.
Type | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (Built-in) | org.apache.hadoop.hive.serde2.OpenCSVSerde (Open-source) |
TINYINT | ||
SMALLINT | ||
INT | ||
BIGINT | ||
BINARY | ||
FLOAT | ||
DOUBLE | ||
DECIMAL(precision,scale) | ||
VARCHAR(n) | ||
CHAR(n) | ||
STRING | ||
DATE | ||
DATETIME | ||
TIMESTAMP | ||
TIMESTAMP_NTZ | ||
BOOLEAN | ||
ARRAY | ||
MAP | ||
STRUCT | ||
JSON |
Format kompresi yang didukung
Saat membaca atau menulis ke file OSS terkompresi, Anda harus menyertakan atribut with serdeproperties dalam pernyataan CREATE TABLE. Untuk informasi selengkapnya, lihat Parameter atribut with serdeproperties.
Format kompresi | com.aliyun.odps.CsvStorageHandler/ TsvStorageHandler (Built-in) | org.apache.hadoop.hive.serde2.OpenCSVSerde (Open-source) |
GZIP | ||
SNAPPY | ||
LZO | ||
ZSTD |
Evolusi skema yang didukung
Operasi | Didukung | Deskripsi |
Add column |
| |
Drop column | Operasi ini tidak disarankan karena dapat menyebabkan ketidaksesuaian antara skema dan data. | |
Change column order | Operasi ini tidak disarankan karena dapat menyebabkan ketidaksesuaian antara skema dan data. | |
Change column data type | Untuk daftar konversi tipe data yang didukung, lihat Ubah Tipe Data Kolom. | |
Rename column | ||
Modify column comment | Komentar harus berupa string yang valid dengan panjang maksimum 1.024 byte. Jika tidak, terjadi error. | |
Change column nullability | Operasi ini tidak didukung. Kolom bersifat nullable secara default. |
Konfigurasi Parameter
Skema tabel eksternal CSV atau TSV dipetakan ke kolom file berdasarkan posisi. Jika jumlah kolom dalam file OSS tidak sesuai dengan jumlah kolom dalam skema tabel eksternal, Anda dapat menggunakan parameter odps.sql.text.schema.mismatch.mode untuk menentukan cara menangani baris yang tidak sesuai.
Jika
odps.sql.text.schema.mismatch.modediatur ke truncate, modifikasi kolom memiliki efek berikut:Data yang sesuai dengan skema baru dapat dibaca seperti yang diharapkan.
Data yang ada yang menggunakan skema lama dibaca berdasarkan skema baru.
Misalnya, jika Anda menambahkan kolom ke tabel, data historis untuk kolom tersebut muncul sebagai NULL saat Anda membaca tabel.
Jika
odps.sql.text.schema.mismatch.modediatur ke ignore, modifikasi kolom memiliki efek berikut:Data yang sesuai dengan skema baru dapat dibaca seperti yang diharapkan.
Data yang ada yang menggunakan skema lama dibaca berdasarkan skema baru.
Misalnya, jika Anda menambahkan kolom ke tabel, seluruh baris data historis yang tidak memiliki kolom baru akan dibuang saat Anda membaca tabel.
Jika
odps.sql.text.schema.mismatch.modediatur ke error, modifikasi kolom memiliki efek berikut:Data yang sesuai dengan skema baru dapat dibaca seperti yang diharapkan.
Data yang ada yang menggunakan skema lama dibaca berdasarkan skema baru.
Misalnya, jika Anda menambahkan kolom ke tabel, terjadi error saat Anda mencoba membaca data historis yang tidak memiliki kolom baru.
Buat tabel eksternal
Sintaksis
Parser teks bawaan
Format CSV
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
STORED BY 'com.aliyun.odps.CsvStorageHandler'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];Format TSV
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
STORED BY 'com.aliyun.odps.TsvStorageHandler'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];Parser open-source bawaan
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name>
(
<col_name> <data_type>,
...
)
[COMMENT <table_comment>]
[PARTITIONED BY (<col_name> <data_type>, ...)]
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
[WITH serdeproperties (
['<property_name>'='<property_value>',...]
)]
STORED AS TEXTFILE
LOCATION '<oss_location>'
[tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];Parameter umum
Untuk informasi selengkapnya mengenai parameter umum, lihat Parameter sintaksis dasar.
Parameter khusus format
Parameter WITH SERDEPROPERTIES
Parser yang berlaku | Parameter | Kasus penggunaan | Deskripsi | Nilai | Default |
Parser data teks bawaan (CsvStorageHandler/TsvStorageHandler) | odps.text.option.gzip.input.enabled | Gunakan properti ini untuk membaca file CSV atau TSV yang dikompresi dalam format GZIP. | Properti kompresi CSV dan TSV. Atur properti ini ke |
| False |
odps.text.option.gzip.output.enabled | Gunakan properti ini untuk menulis data ke OSS dalam format terkompresi GZIP. | Properti kompresi CSV dan TSV. Atur properti ini ke |
| False | |
odps.text.option.header.lines.count | Gunakan properti ini untuk melewati N baris pertama file CSV atau TSV di OSS. | Menentukan jumlah baris header yang dilewati dari awal file saat membaca data. | Bilangan bulat non-negatif | 0 | |
odps.text.option.null.indicator | Gunakan properti ini untuk menentukan string kustom yang merepresentasikan nilai NULL dalam data. | MaxCompute mengurai string yang ditentukan sebagai nilai Misalnya, untuk menginterpretasikan | string | empty string | |
odps.text.option.ignore.empty.lines | Gunakan properti ini untuk menentukan cara menangani baris kosong dalam file CSV atau TSV. | Jika |
| True | |
odps.text.option.encoding | Gunakan properti ini ketika file data tidak menggunakan encoding UTF-8 default. | Encoding yang ditentukan di sini harus sesuai dengan encoding aktual file. Ketidaksesuaian menyebabkan kegagalan pembacaan. |
| UTF-8 | |
odps.text.option.delimiter | Gunakan properti ini untuk menentukan pemisah kolom untuk file CSV atau TSV. | Pastikan pemisah yang ditentukan benar-benar memisahkan kolom dalam file data Anda untuk mencegah ketidaksesuaian data. | Karakter tunggal | Koma (,) | |
odps.text.option.use.quote | Gunakan properti ini ketika bidang dalam file CSV atau TSV berisi line break (CRLF), tanda kutip ganda, atau pemisah kolom. | Ketika bidang dalam file CSV berisi newline, tanda kutip ganda (Anda harus menambahkan |
| False | |
odps.sql.text.option.flush.header | Gunakan properti ini untuk menulis header tabel sebagai baris pertama ke setiap blok file di OSS. | Properti ini hanya berlaku untuk file CSV. |
| False | |
odps.sql.text.schema.mismatch.mode | Gunakan properti ini ketika baris dalam file data memiliki jumlah kolom yang berbeda dengan skema tabel eksternal. | Menentukan cara menangani baris dengan jumlah kolom yang tidak sesuai dengan skema tabel. Catatan: Fitur ini tidak berfungsi jika |
| error | |
odps.text.option.zstd.input.enabled | Gunakan properti ini untuk membaca file CSV atau TSV yang dikompresi dalam format ZSTD. | Properti kompresi CSV dan TSV. Atur properti ini ke True agar MaxCompute dapat membaca file terkompresi ZSTD. Jika tidak, operasi baca gagal. |
| False | |
odps.text.option.zstd.output.enabled | Gunakan properti ini untuk menulis data ke OSS dalam format terkompresi ZSTD. | Properti kompresi CSV dan TSV. Atur properti ini ke True untuk mengompresi data dalam format ZSTD saat menulis ke OSS. Jika tidak, data ditulis tanpa kompresi. |
| False | |
Parser data open-source bawaan (OpenCSVSerde) | separatorChar | Gunakan properti ini untuk menentukan pemisah kolom untuk data CSV yang disimpan sebagai TEXTFILE. | Menentukan pemisah kolom. | Karakter tunggal | Koma (,) |
quoteChar | Gunakan properti ini ketika bidang dalam data CSV berisi karakter khusus seperti pemisah atau line break. | Menentukan karakter yang digunakan untuk mengapit bidang. | Karakter tunggal | None | |
escapeChar | Gunakan properti ini untuk menentukan karakter escape untuk data CSV yang disimpan sebagai TEXTFILE. | Menentukan karakter yang digunakan untuk meng-escape karakter khusus dalam bidang. | Karakter tunggal | None |
Parameter tblproperties
Parser yang berlaku | Parameter | Kasus penggunaan | Deskripsi | Nilai | Default |
Parser data open-source bawaan (OpenCSVSerde) | skip.header.line.count | Gunakan properti ini untuk melewati N baris pertama file CSV yang disimpan sebagai TEXTFILE. | Menentukan jumlah baris header yang dilewati dari awal file saat membaca data. | Bilangan bulat non-negatif | None |
skip.footer.line.count | Gunakan properti ini untuk melewati N baris terakhir file CSV yang disimpan sebagai TEXTFILE. | Menentukan jumlah baris footer yang dilewati dari akhir file saat membaca data. | Bilangan bulat non-negatif | None | |
mcfed.mapreduce.output.fileoutputformat.compress | Gunakan properti ini untuk menulis data TEXTFILE ke OSS dengan kompresi. | Properti kompresi TEXTFILE. Jika diatur ke |
| False | |
mcfed.mapreduce.output.fileoutputformat.compress.codec | Gunakan properti ini untuk menentukan kodek kompresi saat menulis data TEXTFILE terkompresi ke OSS. | Properti kompresi TEXTFILE. Menentukan kodek kompresi untuk output TEXTFILE. Catatan: MaxCompute hanya mendukung empat kodek yang tercantum di kolom |
| None | |
io.compression.codecs | Gunakan properti ini ketika file data OSS dikompresi dalam format Raw-Snappy. | Mengaktifkan MaxCompute untuk membaca data terkompresi Raw-Snappy. Tanpa pengaturan ini, operasi baca gagal. | com.aliyun.odps.io.compress.SnappyRawCodec | None | |
odps.text.option.bad.row.skipping | Gunakan properti ini untuk melewati data kotor dalam file CSV yang disimpan di OSS. | Mengontrol apakah MaxCompute melewati baris yang dianggap sebagai data kotor atau melaporkan error. |
| None |
Menulis data
Untuk detail mengenai sintaksis penulisan di MaxCompute, lihat Sintaksis penulisan.
Kueri dan analisis
Lihat Sintaksis kueri untuk detail mengenai sintaksis SELECT.
Lihat Optimisasi kueri untuk detail mengenai optimisasi rencana kueri.
Lihat BadRowSkipping untuk detail selengkapnya.
BadRowSkipping
Fitur BadRowSkipping memungkinkan Anda melewati baris buruk dalam data CSV yang biasanya menyebabkan kueri gagal. Pengaturan ini mengontrol penanganan error dan tidak memengaruhi cara format data dasar diurai.
Parameter
Parameter tingkat tabel:
odps.text.option.bad.row.skippingrigid: Memaksa pelewatkan. Pengaturan ini tidak dapat diganti oleh konfigurasi tingkat sesi atau proyek.flexible: Mengaktifkan pelewatkan. Pengaturan ini fleksibel, sehingga dapat diganti oleh konfigurasi tingkat sesi atau proyek.
Parameter tingkat
sesi/proyekParameter
odps.sql.unstructured.text.bad.row.skippingdapat mengganti parameter tingkat tabelflexible, tetapi tidak dapat mengganti yangrigid.on: Mengaktifkan fitur. Jika fitur tidak dikonfigurasi untuk tabel, fitur ini diaktifkan secara default.off: Menonaktifkan fitur. Jika tabel dikonfigurasi sebagai flexible, fitur dinonaktifkan. Jika tidak, pengaturan parameter tabel yang digunakan.<null> atau input tidak valid: Konfigurasi tingkat tabel yang digunakan.
odps.sql.unstructured.text.bad.row.skipping.debug.num: Menentukan jumlah hasil error yang dicetak ke stdout di Logview.Nilai maksimum adalah 1000.
Jika nilainya <=0, fitur ini dinonaktifkan.
Jika nilainya tidak valid, fitur ini dinonaktifkan.
Interaksi antara parameter tingkat sesi dan properti tabel
properti tbl
flag sesi
hasil
rigid
on
On, Dipaksa aktif
off
<null>, nilai tidak valid, atau parameter tidak dikonfigurasi
flexible
on
On
off
Off, Dinonaktifkan oleh sesi
<null>, nilai tidak valid, atau parameter tidak dikonfigurasi
On
Not configured
on
On, Diaktifkan oleh sesi
off
Off
<null>, nilai tidak valid, atau parameter tidak dikonfigurasi
Contoh
Siapkan data
Unggah file data uji csv_bad_row_skipping.csv, yang berisi baris buruk, ke direktori di OSS, seperti
oss-mc-test/badrow/.Buat tabel eksternal CSV
Contoh berikut menunjukkan tiga skenario berdasarkan kombinasi berbeda antara parameter tingkat tabel dan tingkat sesi.
Parameter tabel:
odps.text.option.bad.row.skipping = flexible | rigid | <not set>Flag sesi:
odps.sql.unstructured.text.bad.row.skipping = on | off | <not set>
Parameter tidak diatur
-- Tidak ada parameter tingkat tabel yang diatur. Kueri akan gagal pada baris buruk kecuali diganti oleh flag tingkat sesi. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flag ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>';Pelewatkan fleksibel
-- Tabel dikonfigurasi untuk melewati baris buruk, tetapi ini dapat dinonaktifkan oleh flag tingkat sesi. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_flexible ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'flexible' -- Mengaktifkan pelewatkan fleksibel, yang dapat dinonaktifkan pada tingkat sesi. );Pelewatkan kaku
-- Tabel dikonfigurasi untuk memaksa melewati baris buruk. Ini tidak dapat dinonaktifkan pada tingkat sesi. CREATE EXTERNAL TABLE test_csv_bad_data_skipping_rigid ( a INT, b INT ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) location '<oss://<your-bucket-name>/<your-file-path>/>' tblproperties ( 'odps.text.option.bad.row.skipping' = 'rigid' -- Memaksa pelewatkan aktif. );Verifikasi hasil kueri
Parameter tidak diatur
-- Perintah berikut mengaktifkan pelewatkan, tetapi segera diganti oleh perintah berikutnya dalam contoh ini. SET odps.sql.unstructured.text.bad.row.skipping=on; -- Perintah ini menonaktifkan pelewatkan dan merupakan pengaturan aktif untuk kueri SELECT di bawah, menyebabkan kueri gagal. SET odps.sql.unstructured.text.bad.row.skipping=off; -- Anda dapat menggunakan perintah ini untuk mencetak detail baris yang dilewati saat pelewatkan diaktifkan. Tidak berpengaruh di sini karena kueri gagal. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flag;Kueri gagal dengan error berikut: FAILED: ODPS-0123131:User defined function exception
Pelewatkan fleksibel
-- Perintah berikut mengaktifkan pelewatkan, tetapi segera diganti oleh perintah berikutnya dalam contoh ini. SET odps.sql.unstructured.text.bad.row.skipping=on; -- Perintah ini menonaktifkan pelewatkan, mengganti pengaturan 'flexible' tabel. Ini merupakan pengaturan aktif untuk kueri SELECT di bawah, menyebabkan kueri gagal. SET odps.sql.unstructured.text.bad.row.skipping=off; -- Cetak detail hingga 10 baris buruk pada tingkat sesi. Maksimum adalah 1.000. Nilai 0 atau kurang menonaktifkan pencetakan. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_flexible;Kueri gagal dengan error berikut: FAILED: ODPS-0123131:User defined function exception
Pelewatkan kaku
-- Perintah ini berlebihan karena pengaturan 'rigid' sudah memberlakukan pelewatkan. SET odps.sql.unstructured.text.bad.row.skipping=on; -- Perintah ini mencoba menonaktifkan pelewatkan, tetapi diabaikan karena pengaturan tabel 'rigid' tidak dapat diganti. SET odps.sql.unstructured.text.bad.row.skipping=off; -- Perintah ini mencetak detail hingga 10 baris buruk yang dilewati oleh pengaturan 'rigid'. SET odps.sql.unstructured.text.bad.row.skipping.debug.num=10; SELECT * FROM test_csv_bad_data_skipping_rigid;Hasil berikut dikembalikan:
+------------+------------+ | a | b | +------------+------------+ | 1 | 26 | | 5 | 37 | +------------+------------+
Kompatibilitas tipe fleksibel dengan Smart Parse
Untuk tabel eksternal berformat CSV di OSS, MaxCompute SQL menggunakan tipe data 2.0 untuk operasi baca dan tulis. Sebelumnya, hanya nilai dalam format ketat yang didukung. Fitur ini menyediakan kompatibilitas tipe fleksibel untuk membaca berbagai format nilai dari file CSV. Aturan penguraian spesifik dijelaskan di bawah ini.
Type | Input sebagai string | Output sebagai string | Deskripsi |
BOOLEAN |
Catatan Operasi |
| Penguraian gagal jika string input bukan salah satu nilai yang didukung. |
TINYINT |
Catatan
|
| Bilangan bulat 8-bit. Terjadi error jika nilai berada di luar rentang |
SMALLINT | Bilangan bulat 16-bit. Terjadi error jika nilai berada di luar rentang | ||
INT | Bilangan bulat 32-bit. Terjadi error jika nilai berada di luar rentang | ||
BIGINT | Bilangan bulat 64-bit. Terjadi error jika nilai berada di luar rentang Catatan Nilai | ||
FLOAT |
Catatan
|
| Nilai khusus (tidak peka huruf besar/kecil) meliputi NaN, Inf, -Inf, Infinity, dan -Infinity. Terjadi error jika nilai berada di luar rentang. Jika presisi melebihi batas, nilai dibulatkan. |
DOUBLE |
Catatan
|
| Nilai khusus (tidak peka huruf besar/kecil) meliputi NaN, Inf, -Inf, Infinity, dan -Infinity. Terjadi error jika nilai berada di luar rentang. Jika presisi melebihi batas, nilai dibulatkan. |
DECIMAL (precision, scale) Contoh: DECIMAL(15,2) |
Catatan
|
| Terjadi error jika bagian integer berisi lebih dari Terjadi error. Jika bagian pecahan melebihi skala, nilai dibulatkan dan dipotong. |
CHAR(n) Contoh: CHAR(7) |
|
| Panjang maksimum adalah 255. Jika string input lebih pendek dari n, diisi dengan spasi di akhir, tetapi spasi ini diabaikan dalam perbandingan. Jika string input lebih panjang dari n, dipotong. |
VARCHAR(n) Contoh: VARCHAR(7) |
|
| Panjang maksimum adalah 65.535. Jika string input lebih panjang dari n, dipotong. |
STRING |
|
| Panjang maksimum adalah 8 MB. |
DATE |
Catatan Anda juga dapat mengatur properti |
|
|
TIMESTAMP_NTZ Catatan OpenCsvSerde tidak mendukung tipe ini karena tidak kompatibel dengan format data Hive. |
|
|
|
DATETIME |
| Dengan asumsi zona waktu sistem adalah Asia/Shanghai:
|
|
TIMESTAMP |
| (Dengan asumsi zona waktu sistem adalah Asia/Shanghai)
|
|
Aturan Umum
Untuk semua tipe data, string kosong dalam file data CSV diurai sebagai NULL saat dibaca ke dalam tabel.
Tipe Data yang Tidak Didukung
Tipe kompleks (STRUCT, ARRAY, MAP): Tidak didukung. Nilai tipe ini sering berisi karakter seperti koma (
,), yang dapat bertentangan dengan pemisah CSV umum dan menyebabkan kegagalan penguraian.BINARY dan INTERVAL: Saat ini tidak didukung. Jika Anda membutuhkan dukungan untuk tipe ini, hubungi dukungan teknis MaxCompute.
Tipe Numerik (INT, DOUBLE, dll.)
Untuk tipe data numerik seperti INT, SMALLINT, TINYINT, BIGINT, FLOAT, DOUBLE, dan DECIMAL, MaxCompute menyediakan kemampuan penguraian default yang luas.
Jika Anda hanya perlu mengurai string numerik dasar, Anda dapat mengatur properti
odps.text.option.smart.parse.levelkenaiveditblproperties. Dalam mode naive, parser hanya mendukung format sederhana seperti "123" dan "123.456". Mengurai format string lain menyebabkan error.
Tipe Tanggal dan Waktu (DATE, TIMESTAMP, dll.)
Kelas
java.time.format.DateTimeFormattermemproses keempat tipe tanggal dan waktu:DATE, DATETIME, TIMESTAMP, dan TIMESTAMP_NTZ.Format default: MaxCompute memiliki beberapa format penguraian bawaan.
Format kustom:
Anda dapat menentukan beberapa format penguraian dan satu format output dengan mengatur properti
odps.text.option.<date|datetime|timestamp|timestamp_ntz>.io.formatditblproperties.Gunakan simbol hash (
#) untuk memisahkan beberapa pola penguraian.Format kustom memiliki prioritas lebih tinggi daripada format bawaan. Pola kustom pertama digunakan untuk output.
Contoh: Jika Anda menentukan string format kustom untuk tipe DATE sebagai
pattern1#pattern2#pattern3, MaxCompute dapat mengurai string yang sesuai denganpattern1,pattern2, ataupattern3. Namun, saat menulis data ke file, output selalu menggunakan format yang ditentukan olehpattern1. Untuk informasi selengkapnya, lihat DateTimeFormatter.
Catatan Penting Mengenai Pola Zona Waktu 'z'
Hindari menggunakan 'z' (nama zona waktu) dalam format kustom, terutama untuk pengguna di Tiongkok, karena bersifat ambigu.
Sebagai gantinya, gunakan 'x' (offset zona) atau 'VV' (ID zona waktu) untuk pola zona waktu.
Contoh: 'CST' biasanya berarti China Standard Time (UTC+8) di Tiongkok. Namun, ketika
java.time.format.DateTimeFormattermengurai 'CST', ia menginterpretasikannya sebagai US Central Standard Time (UTC-6), yang dapat menyebabkan hasil input atau output yang tidak terduga.
Contoh
Prasyarat
Proyek MaxCompute. Lihat Buat proyek MaxCompute.
Bucket OSS di wilayah yang sama dengan proyek MaxCompute Anda. Lihat Buat bucket dan Kelola folder. MaxCompute dapat membuat folder OSS secara otomatis — Anda tidak perlu membuatnya sebelum menjalankan SQL.
Izin akses OSS melalui akun Alibaba Cloud, pengguna Resource Access Management (RAM), atau peran RAM. Lihat Otorisasi akses dalam mode STS untuk OSS.
Izin
CreateTabledi proyek MaxCompute Anda. Lihat Izin MaxCompute.
Buat tabel eksternal OSS dengan parser teks bawaan
Contoh 1: Tabel non-partisi
Petakan tabel eksternal ke direktori
Demo1/dari data sampel. Gunakan perintah berikut untuk membuat tabel eksternal OSS.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external1 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo1/'; -- Anda dapat menjalankan perintah `desc extended mc_oss_csv_external1;` untuk melihat skema tabel eksternal OSS yang dibuat.Contoh ini menggunakan peran RAM
aliyunodpsdefaultrole. Jika Anda menggunakan peran RAM berbeda, gantialiyunodpsdefaultroledengan nama peran RAM target Anda dan berikan izin yang diperlukan untuk mengakses OSS.Kueri tabel eksternal non-partisi.
SELECT * FROM mc_oss_csv_external1;Perintah mengembalikan hasil berikut:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | | 1 | 10 | 31 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | +------------+------------+------------+------------+------------------+-------------------+------------+----------------+Tulis data ke tabel eksternal non-partisi dan periksa bahwa data berhasil ditulis.
INSERT INTO mc_oss_csv_external1 VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW'); SELECT * FROM mc_oss_csv_external1 WHERE recordId=12;Perintah mengembalikan hasil berikut:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+Verifikasi bahwa file baru muncul di direktori
Demo1/di OSS.
Contoh 2: Tabel partisi
Petakan tabel eksternal ke direktori
Demo2/dari data sampel. Perintah contoh berikut membuat tabel eksternal OSS terpartisi.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external2 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING ) PARTITIONED BY ( direction STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo2/'; -- Anda dapat menjalankan perintah `DESC EXTENDED mc_oss_csv_external2;` untuk melihat skema tabel eksternal yang dibuat.Contoh ini menggunakan peran RAM
aliyunodpsdefaultrole. Jika Anda menggunakan peran RAM berbeda, gantialiyunodpsdefaultroledengan nama peran RAM target Anda dan berikan izin yang diperlukan untuk mengakses OSS.Impor data partisi. Jika Anda membuat tabel eksternal OSS terpartisi, Anda juga harus mengimpor data partisi. Untuk informasi selengkapnya, lihat Tabel eksternal OSS.
MSCK REPAIR TABLE mc_oss_csv_external2 ADD PARTITIONS; -- Ini setara dengan pernyataan berikut. ALTER TABLE mc_oss_csv_external2 ADD PARTITION (direction = 'N') PARTITION (direction = 'NE') PARTITION (direction = 'S') PARTITION (direction = 'SW') PARTITION (direction = 'W');Kueri tabel eksternal terpartisi.
SELECT * FROM mc_oss_csv_external2 WHERE direction='NE';Perintah mengembalikan hasil berikut:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+Tulis data ke tabel eksternal terpartisi dan periksa bahwa data berhasil ditulis.
INSERT INTO mc_oss_csv_external2 PARTITION(direction='NE') VALUES(1,12,76,1,46.81006,-92.08174,'9/14/2014 0:10'); SELECT * FROM mc_oss_csv_external2 WHERE direction='NE' AND recordId=12;Perintah mengembalikan hasil berikut:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+Periksa bahwa file baru dihasilkan di direktori
Demo2/direction=NEdi OSS.
Contoh 3: Data terkompresi
Contoh ini menunjukkan cara membuat tabel eksternal CSV terkompresi GZIP dan melakukan operasi baca dan tulis.
Buat tabel internal dan masukkan data uji untuk pengujian tulis berikutnya.
CREATE TABLE vehicle_test( vehicleid INT, recordid INT, patientid INT, calls INT, locationlatitute DOUBLE, locationlongtitue DOUBLE, recordtime STRING, direction STRING ); INSERT INTO vehicle_test VALUES (1,1,51,1,46.81006,-92.08174,'9/14/2014 0:00','S');Buat tabel eksternal CSV terkompresi GZIP dan petakan ke direktori
Demo3/(yang berisi data terkompresi) dari data sampel. Perintah contoh berikut membuat tabel eksternal OSS.CREATE EXTERNAL TABLE IF NOT EXISTS mc_oss_csv_external3 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) PARTITIONED BY (dt STRING) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole', 'odps.text.option.gzip.input.enabled'='true', 'odps.text.option.gzip.output.enabled'='true' ) LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo3/'; -- Impor data partisi. MSCK REPAIR TABLE mc_oss_csv_external3 ADD PARTITIONS; -- Anda dapat menjalankan perintah `DESC EXTENDED mc_oss_csv_external3;` untuk melihat skema tabel eksternal yang dibuat.Contoh ini menggunakan peran RAM
aliyunodpsdefaultrole. Jika Anda menggunakan peran RAM berbeda, gantialiyunodpsdefaultroledengan nama peran RAM target Anda dan berikan izin yang diperlukan untuk mengakses OSS.Gunakan klien MaxCompute untuk membaca data dari OSS:
CatatanJika data terkompresi di OSS dalam format data open-source, Anda harus menambahkan perintah
set odps.sql.hive.compatible=true;sebelum pernyataan SQL dan mengirimkannya bersama untuk dieksekusi.--Aktifkan pemindaian tabel penuh hanya untuk sesi saat ini. SET odps.sql.allow.fullscan=true; SELECT recordId, patientId, direction FROM mc_oss_csv_external3 WHERE patientId > 25;Perintah mengembalikan hasil berikut:
+------------+------------+------------+ | recordid | patientid | direction | +------------+------------+------------+ | 1 | 51 | S | | 3 | 48 | NE | | 4 | 30 | W | | 5 | 47 | S | | 7 | 53 | N | | 8 | 63 | SW | | 10 | 31 | N | +------------+------------+------------+Baca data dari tabel internal dan tulis ke tabel eksternal OSS.
Anda dapat mengeksekusi perintah
INSERT OVERWRITEatauINSERT INTOpada tabel eksternal dari klien MaxCompute untuk menulis data ke OSS.INSERT INTO TABLE mc_oss_csv_external3 PARTITION (dt='20250418') SELECT * FROM vehicle_test;Setelah perintah berhasil dijalankan, Anda dapat melihat file yang diekspor di direktori OSS.
Buat tabel eksternal dengan baris header
Buat direktori Demo11 di bucket oss-mc-test dari data sampel, dan jalankan pernyataan berikut:
--Buat tabel eksternal.
CREATE EXTERNAL TABLE mf_oss_wtt
(
id BIGINT,
name STRING,
tran_amt DOUBLE
)
STORED BY 'com.aliyun.odps.CsvStorageHandler'
WITH serdeproperties (
'odps.text.option.header.lines.count' = '1',
'odps.sql.text.option.flush.header' = 'true'
)
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/Demo11/';
--Masukkan data.
INSERT OVERWRITE TABLE mf_oss_wtt VALUES (1, 'val1', 1.1),(2, 'value2', 1.3);
--Kueri data.
--Saat membuat tabel, Anda dapat mendefinisikan semua kolom sebagai STRING. Jika tidak, terjadi error saat membaca header.
--Atau, tambahkan parameter 'odps.text.option.header.lines.count' = '1' ke definisi tabel untuk melewati header.
SELECT * FROM mf_oss_wtt;Contoh ini menggunakan peran RAM aliyunodpsdefaultrole. Jika Anda menggunakan peran RAM berbeda, ganti aliyunodpsdefaultrole dengan nama peran RAM target Anda dan berikan izin yang diperlukan untuk mengakses OSS.
Perintah mengembalikan hasil berikut:
+----------+--------+------------+
| id | name | tran_amt |
+----------+--------+------------+
| 1 | val1 | 1.1 |
| 2 | value2 | 1.3 |
+----------+--------+------------+Buat tabel eksternal dengan kolom tidak sesuai
Buat direktori
demodi bucketoss-mc-testdari data sampel dan unggah filetest.csv. Filetest.csvberisi konten berikut:1,kyle1,this is desc1 2,kyle2,this is desc2,this is two 3,kyle3,this is desc3,this is three, I have 4 columnsBuat tabel eksternal.
Atur metode penanganan untuk baris dengan jumlah kolom tidak konsisten ke
TRUNCATE.-- Hapus tabel. DROP TABLE test_mismatch; -- Buat tabel eksternal. CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch ( id string, name string, dect string, col4 string ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'truncate') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';Tentukan metode penanganan untuk baris dengan jumlah kolom tidak konsisten sebagai
IGNORE.-- Hapus tabel. DROP TABLE test_mismatch01; -- Buat tabel eksternal. CREATE EXTERNAL TABLE IF NOT EXISTS test_mismatch01 ( id STRING, name STRING, dect STRING, col4 STRING ) STORED BY 'com.aliyun.odps.CsvStorageHandler' WITH serdeproperties ('odps.sql.text.schema.mismatch.mode' = 'ignore') LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/';Kueri data di tabel.
Kueri tabel
test_mismatch.SELECT * FROM test_mismatch; --Hasil yang dikembalikan +----+-------+---------------+---------------+ | id | name | dect | col4 | +----+-------+---------------+---------------+ | 1 | kyle1 | this is desc1 | NULL | | 2 | kyle2 | this is desc2 | this is two | | 3 | kyle3 | this is desc3 | this is three | +----+-------+---------------+---------------+Kueri tabel
test_mismatch01.SELECT * FROM test_mismatch01; --Hasil yang dikembalikan +----+-------+----------------+-------------+ | id | name | dect | col4 | +----+-------+----------------+-------------+ | 2 | kyle2 | this is desc2 | this is two +----+-------+----------------+-------------+
Buat tabel eksternal dengan parser open-source
Contoh ini menunjukkan cara menggunakan parser open source bawaan untuk membuat tabel eksternal OSS guna membaca file yang dipisahkan koma sambil mengabaikan baris header dan footer.
Buat direktori
demo-testdi bucketoss-mc-testdari data sampel dan unggah file test.csv.File uji berisi data berikut:
1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,NBuat tabel eksternal, tentukan koma sebagai pemisah, dan atur parameter untuk mengabaikan baris header dan footer.
CREATE EXTERNAL TABLE ext_csv_test08 ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT serde 'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH serdeproperties ( "separatorChar" = "," ) stored AS textfile location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/***/' -- Atur parameter untuk mengabaikan baris header dan footer. TBLPROPERTIES ( "skip.header.line.COUNT"="1", "skip.footer.line.COUNT"="1" ) ;Baca data dari tabel eksternal.
SELECT * FROM ext_csv_test08; -- Hasil mencakup 8 baris data karena baris header dan footer diabaikan. +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+ | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | NE | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | W | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | S | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | N | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | SW | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/15/2014 0:00 | NE | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+
Buat tabel eksternal CSV dengan tipe waktu kustom
Untuk detail mengenai format penguraian dan output untuk tipe waktu kustom dalam CSV, lihat Kompatibilitas tipe fleksibel dengan Smart Parse.
Buat tabel eksternal CSV yang menggunakan berbagai tipe data waktu, seperti
DATE,DATETIME,TIMESTAMP, danTIMESTAMP_NTZ.CREATE EXTERNAL TABLE test_csv ( col_date DATE, col_datetime DATETIME, col_timestamp TIMESTAMP, col_timestamp_ntz TIMESTAMP_NTZ ) STORED BY 'com.aliyun.odps.CsvStorageHandler' LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo/' TBLPROPERTIES ( 'odps.text.option.date.io.format' = 'MM/dd/yyyy', 'odps.text.option.datetime.io.format' = 'yyyy-MM-dd-HH-mm-ss x', 'odps.text.option.timestamp.io.format' = 'yyyy-MM-dd HH-mm-ss VV', 'odps.text.option.timestamp_ntz.io.format' = 'yyyy-MM-dd HH:mm:ss.SS' ); INSERT OVERWRITE test_csv VALUES(DATE'2025-02-21', DATETIME'2025-02-21 08:30:00', TIMESTAMP'2025-02-21 12:30:00', TIMESTAMP_NTZ'2025-02-21 16:30:00.123456789');Setelah data dimasukkan, konten file CSV adalah sebagai berikut:
02/21/2025,2025-02-21-08-30-00 +08,2025-02-21 12-30-00 Asia/Shanghai,2025-02-21 16:30:00.12Kueri data lagi untuk melihat hasilnya.
SELECT * FROM test_csv;Perintah mengembalikan hasil berikut:
+------------+---------------------+---------------------+------------------------+ | col_date | col_datetime | col_timestamp | col_timestamp_ntz | +------------+---------------------+---------------------+------------------------+ | 2025-02-21 | 2025-02-21 08:30:00 | 2025-02-21 12:30:00 | 2025-02-21 16:30:00.12 | +------------+---------------------+---------------------+------------------------+
FAQ
Error ketidaksesuaian jumlah kolom
Gejala
Error ini terjadi ketika jumlah kolom dalam baris file CSV atau TSV tidak sesuai dengan yang didefinisikan dalam DDL tabel eksternal. MaxCompute melaporkan error serupa dengan
FAILED: ODPS-0123131:User defined function exception - Traceback:java.lang.RuntimeException: SCHEMA MISMATCH:xxx.Resolusi
Anda dapat mengontrol cara MaxCompute menangani ketidaksesuaian dengan mengatur parameter
odps.sql.text.schema.mismatch.modepada tingkat sesi:SET odps.sql.text.schema.mismatch.mode=error: Menggagalkan kueri ketika terjadi ketidaksesuaian jumlah kolom. Ini adalah perilaku default.SET odps.sql.text.schema.mismatch.mode=truncate: Jika baris memiliki lebih banyak kolom daripada yang didefinisikan dalam DDL tabel eksternal, kolom tambahan dibuang. Jika baris memiliki lebih sedikit kolom, kolom yang hilang diisi dengan NULL.