Katalog adalah indeks metadata Spark, yaitu tempat nama seperti basis data, tabel, dan view terdaftar beserta lokasi datanya. Setiap kali SQL menemukan nama tabel di dalam FROM, yang diterima kueri bukan data, melainkan entri katalog yang menerjemahkan nama tersebut menjadi lokasi berkas atau rencana. Topik ini menjelajahi katalog melalui API spark.catalog, mulai dari basis data default, mendaftarkan tabel sementara, sampai memeriksa keberadaan nama sebelum dipakai.
Ruang nama: basis data, tabel, dan view#
Katalog menyusun metadata dalam tiga lapis. Lapis paling atas adalah database, yang di Spark lebih tepat disebut namespace, dan setiap sesi selalu berangkat dari satu basis data bernama default. Di dalamnya terdaftar tabel dan view. Pada katalog, perbedaan keduanya tipis, karena keduanya sama-sama entri bernama, tetapi tabel biasanya menunjuk ke data yang tersimpan sedangkan view menunjuk ke rencana kueri.
Entri terbagi lagi menurut masa hidupnya. Tabel permanen hidup lintas sesi karena datanya tertulis di penyimpanan dan metadatanya disimpan oleh katalog eksternal atau direktori warehouse. Sebaliknya temp view dari topik pertama modul ini tidak pernah masuk penyimpanan, dan katalog mencatatnya sebagai entri sementara milik sesi. Dengan begitu dua sesi yang berjalan bersamaan dapat memakai nama view yang sama tanpa saling mengganggu.
Menjelajah katalog dengan API#
Skrip berikut memeriksa isi katalog pada sesi yang baru dibuat, mendaftarkan sebuah temp view, lalu memeriksanya kembali. Perhatikan bahwa tidak ada satu pun perintah SQL yang dijalankan, karena seluruh operasi di sini murni manipulasi metadata.
from pyspark.sql import SparkSession
spark = (
SparkSession.builder
.master("local[2]")
.appName("uji-katalog")
.getOrCreate()
)
print("=== basis data yang tersedia ===")
for db in spark.catalog.listDatabases():
print(db.name, "->", db.locationUri)
print("database saat ini:", spark.catalog.currentDatabase())
spark.range(3).createOrReplaceTempView("data_sementara")
print("=== tabel dan view yang terdaftar ===")
for t in spark.catalog.listTables():
print(t.name, "| tipe:", t.tableType, "| database:", t.database)
print("tabel ada?", spark.catalog.tableExists("data_sementara"))
spark.stop()WARNING: Using incubator modules: jdk.incubator.vector
=== basis data yang tersedia ===
default -> file:/home/kal/my-project/content/spark/sql-di-spark/katalog/spark-warehouse
database saat ini: default
=== tabel dan view yang terdaftar ===
data_sementara | tipe: TEMPORARY | database: None
tabel ada? TrueKeluaran pertama memperlihatkan hanya satu basis data bernama default, yang lokasinya menunjuk ke direktori spark-warehouse di sekitar skrip. Direktori itulah tempat tabel permanen dikelola apabila kelak dibuat dengan saveAsTable pada modul berkas dan format. Setelah view didaftarkan, daftar tabel memuat satu entri data_sementara bertipe TEMPORARY dengan kolom database kosong karena temp view memang tidak melekat pada basis data mana pun.
Fungsi tableExists menutup skrip dengan pemeriksaan keberadaan nama. Metode ini praktis pada skrip yang bisa dijalankan berulang, karena pembuatan view atau tabel dapat dibuat bersyarat atas hasil pemeriksaan, sehingga tidak perlu menangkap error TABLE_OR_VIEW_NOT_FOUND hanya untuk mengetahui bahwa nama sudah atau belum ada.
Dari katalog ke rencana eksekusi#
Keterkaitan katalog dengan eksekusi bisa dirasakan ketika SQL menyebut nama. Apabila nama menunjuk ke temp view, katalog menyisipkan rencana DataFrame yang terdaftar. Apabila nama menunjuk ke tabel berformat Parquet, katalog menyediakan lokasi berkas dan schema tercatat sehingga pemindaian langsung membaca hanya kolom yang disebut. Perbedaan kedua jalur ini tidak terlihat di permukaan SQL, tetapi keduanya berawal dari pencarian entri katalog yang sama.
API katalog juga membantu ketika skrip perlu bekerja secara dinamis, misalnya memeriksa daftar tabel sebelum membersihkannya, atau membaca kolom sebuah tabel dengan spark.catalog.listColumns() sebelum menyusun kueri. Untuk kebutuhan lebih dalam seperti pembaruan metadata, Spark 4 menyediakan DataFrameView dan antarmuka katalog yang lebih kaya, namun pada tahap ini pemahaman bahwa katalog adalah buku telepon dari nama ke data sudah cukup sebagai fondasi menuju modul berkas dan format.
Urutan resolusi nama menjadi detail yang menentukan perilaku ketika dua entri memakai nama yang sama. Apabila sebuah temp view dibuat dengan nama yang sama dengan tabel permanen yang terdaftar pada katalog, kueri yang menyebut nama tersebut mendahulukan temp view milik sesi, dan tabel di belakangnya tidak tersentuh. Perilaku ini berguna untuk menguji ulang kueri produksi terhadap data yang lebih kecil, karena tabel riil dapat digantikan oleh temp view berisi sampel tanpa menyentuh kueri apa pun. Konsekuensi sebaliknya perlu diingat, yaitu sebuah temp view yang tertinggal dapat menutupi tabel sungguhan secara diam-diam, dan pemanggilan spark.catalog.listTables() beserta tipe entrinya adalah cara cepat menemukan keadaan seperti itu.
Kesalahan umum#
Kesalahan pertama adalah mengira listTables() mengembalikan tabel dari semua basis data sekaligus. Tanpa argumen, pemanggilan hanya memeriksa basis data saat ini, dan temp view muncul dengan kolom database kosong. Perbaikannya adalah memberi argumen nama basis data apabila tabel lain ingin diperiksa, misalnya spark.catalog.listTables("default").
Kesalahan kedua adalah berasumsi nama yang bisa di-SELECT pasti terdaftar di listTables() sesi lain. Temp view hidup di sesi pembuatnya, sehingga skrip kedua yang membuka sesi baru tidak melihatnya meskipun dijalankan berdampingan. Apabila view perlu dibagikan lintas sesi, jalurnya adalah global temp view yang diakses melalui namespace khusus global_temp.
Kesalahan ketiga adalah menghapus atau membuat ulang tabel dengan mengeksekusi SQL tanpa pemeriksaan terlebih dahulu. Pola DROP TABLE IF EXISTS sah pada SQL, tetapi pada alur Python yang dinamis, tableExists() membuat keputusan programatik lebih mudah dibaca daripada menangkap error dan melanjutkan.
Ringkasan#
- Katalog adalah lapisan metadata yang menerjemahkan nama tabel dan view menjadi rencana atau lokasi data saat SQL dijalankan.
- Setiap sesi berangkat dari basis data
defaultyang direktori warehouse-nya menampung tabel permanen kelak. spark.catalog.listDatabases(),listTables(), dantableExists()memungkinkan skrip memeriksa metadata tanpa menjalankan kueri.- Temp view tercatat bertipe
TEMPORARYtanpa basis data karena hidup hanya pada sesi pembuatnya.
Referensi#
- pyspark.sql.Catalog — Apache Spark — Referensi lengkap API katalog beserta semua metode pencarian metadata.
- Namespaces dan tables pada Spark SQL — Panduan referensi SQL yang menjelaskan hierarki katalog, namespace, dan tabel.
- pyspark.sql.Catalog.listTables — Apache Spark — Dokumentasi listTables beserta perilaku argumen basis data.