psql adalah terminal interaktif resmi PostgreSQL dan akan menjadi alat kerja utama kita sepanjang course ini. Berbeda dengan alat grafis, psql hanya membutuhkan terminal dan tetap tersedia di server produksi mana pun — kebiasaan yang kita bangun di sini terbawa sampai ke server sungguhan. Pada chapter ini kita akan membedah meta-command (perintah yang diawali backslash), mengubah format tampilan hasil query, menjalankan psql secara non-interaktif, dan membuat psql berhenti di perintah pertama yang gagal.

Mode Interaktif dan Prompt psql #

Mengetik psql di terminal membuka mode interaktif: sebuah prompt yang menunggu perintah kita. Jika tidak menyebut database, psql mencoba masuk ke database bernama sama dengan nama user kita; karena itu kebiasaan yang baik adalah menyebutnya secara eksplisit, misalnya psql -d latihan.

Prompt psql juga membocorkan status koneksi kita. Akhiran # menandakan kita terhubung sebagai superuser — contohnya postgres=# — sedangkan akhiran > menandakan user biasa, seperti budi@latihan=>. Perbedaan kecil ini penting diingat karena superuser boleh melakukan apa saja, termasuk hal-hal yang merusak.

Keluar dari mode interaktif bisa dengan meta-command \q atau menekan Ctrl+D. Perintah SQL yang belum diakhiri titik koma tidak dieksekusi — psql akan terus menunggu baris lanjutan dengan prompt ->, hal yang sering membuat pemula mengira terminalnya macet.

Meta-Command: Perintah yang Diawali Backslash #

Selain perintah SQL, psql mengenali perintahnya sendiri yang diawali backslash (\). Meta-command ini diproses oleh psql di sisi client, bukan dikirim ke server sebagai SQL — psql-lah yang menerjemahkannya menjadi query ke catalog atau mengubah perilaku tampilannya. Karena itu meta-command tidak perlu diakhiri titik koma.

Meta-command yang akan paling sering kita pakai:

Meta-commandFungsi
\dtDaftar tabel di database saat ini
\d nama_tabelStruktur tabel: kolom, tipe, constraint, index
\lDaftar database di cluster
\duDaftar role beserta atributnya
\dnDaftar schema
\conninfoRingkasan koneksi aktif: database, user, host, port
\xBerganti antara tampilan normal dan expanded
\timingMenampilkan durasi setiap query
\i nama_fileMenjalankan file SQL dari dalam mode interaktif
\?Bantuan seluruh meta-command
\qKeluar dari psql

Sebelum mencoba, kita perlu sebuah tabel contoh di database. File berikut membuat tabel pelanggan berisi tiga baris, lalu menampilkan isinya sebagai verifikasi:

sql buat-tabel.sql
CREATE TABLE pelanggan (
    id    integer PRIMARY KEY,
    nama  text NOT NULL,
    email text NOT NULL,
    kota  text NOT NULL
);

INSERT INTO pelanggan (id, nama, email, kota) VALUES
    (1, 'Budi Santoso', '[email protected]', 'Jakarta'),
    (2, 'Siti Rahayu', '[email protected]', 'Bandung'),
    (3, 'Andi Wijaya', '[email protected]', 'Surabaya');

SELECT id, nama, email, kota
FROM pelanggan
ORDER BY id;

Output yang Dihasilkan:

text
CREATE TABLE
INSERT 0 3
 id |     nama     |      email       |   kota   
----+--------------+------------------+----------
  1 | Budi Santoso | [email protected] | Jakarta
  2 | Siti Rahayu  | [email protected] | Bandung
  3 | Andi Wijaya  | [email protected] | Surabaya
(3 rows)

Menjelajahi Isi Database #

Sejumlah meta-command penjelajahan bisa dijalankan berurutan dalam satu file SQL. File berikut memperlihatkan lima di antaranya bekerja pada tabel pelanggan yang baru saja kita buat:

-- Ringkasan koneksi yang sedang aktif
\conninfo

-- Daftar tabel di schema pencarian saat ini
\dt

-- Struktur tabel pelanggan
\d pelanggan

-- Daftar schema di database ini
\dn

-- Daftar database yang namanya dimulai dengan "post"
\l post*

Output yang Dihasilkan:

text
You are connected to database "pgtutor_6694331b32" as user "postgres" via socket in "/home/z/my-project/pgrun" at port "54329".
           List of relations
 Schema |   Name    | Type  |  Owner   
--------+-----------+-------+----------
 public | pelanggan | table | postgres
(1 row)

             Table "public.pelanggan"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | integer |           | not null | 
 nama   | text    |           | not null | 
 email  | text    |           | not null | 
 kota   | text    |           | not null | 
Indexes:
    "pelanggan_pkey" PRIMARY KEY, btree (id)

      List of schemas
  Name  |       Owner       
--------+-------------------
 public | pg_database_owner
(1 row)

                                              List of databases
   Name   |  Owner   | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges 
----------+----------+----------+-----------------+---------+-------+--------+-----------+-------------------
 postgres | postgres | UTF8     | libc            | C       | C     |        |           | 
(1 row)

Mari kita bedah hasil kelima meta-command tersebut satu per satu:

  1. \conninfo: mencetak satu kalimat ringkasan — database aktif, user, jalur koneksi, dan port. Baris pada output di atas diambil dari lingkungan pengujian materi ini: koneksi lewat unix socket pada port 54329 ke database sementara khusus chapter (bernama pgtutor_...) tempat seluruh contoh course ini dijalankan. Di komputer Anda yang tampil adalah database yang sedang Anda buka, misalnya latihan.
  2. \dt: menampilkan tabel pelanggan beserta schema-nya (public) dan pemiliknya. Kolom Owner terisi postgres karena user yang membuat tabel adalah superuser tersebut.
  3. \d pelanggan: membedah satu tabel — empat kolom dengan tipe dan aturan not null, plus index pelanggan_pkey yang otomatis dibuat oleh PRIMARY KEY pada kolom id.
  4. \dn: menampilkan schema di database ini. Setiap database baru PostgreSQL dimulai dengan schema public sebagai wadah bawaan untuk objek-objek kita.
  5. \l post*: menampilkan daftar database yang namanya cocok dengan pola post*. Tanpa pola, \l menampilkan seluruh database di cluster — daftarnya berbeda-beda di tiap server sehingga di sini kita memfilter dengan pola. Karakter * pada pola berarti “deretan karakter apa pun”, jadi post* menjaring postgres. Database template0 dan template1 tidak tampil karena namanya tidak berawalan post; keduanya adalah cetakan bawaan untuk membuat database baru.

Perintah \l post* memperlihatkan satu fitur menarik psql: hampir semua meta-command daftar menerima pola pencarian, misalnya \d pel* untuk semua tabel berawalan pel.

Melihat Daftar Role #

Meta-command \du menampilkan daftar role di cluster beserta atributnya. Karena isi daftar ini benar-benar bergantung pada server tempatnya dijalankan, output berikut adalah hasil nyata pada lingkungan pengujian materi ini — di cluster Anda, daftar dan atributnya dapat berbeda:

sql meta-roles.sql
-- Daftar role di cluster; isinya berbeda-beda antar lingkungan
\du

Output yang Dihasilkan:

text
                                List of roles
   Role name    |                         Attributes                         
----------------+------------------------------------------------------------
 kasir          | Cannot login
 pengguna_biasa | Cannot login
 postgres       | Superuser, Create role, Create DB, Replication, Bypass RLS

Baris postgres menampilkan superuser bawaan dengan atribut lengkapnya: boleh membuat role, membuat database, dan melakukan replikasi. Setelah kita membuat role sendiri di chapter Lingkungan Pengembangan, role baru itu akan muncul di daftar yang sama.

Tampilan Expanded untuk Kolom yang Banyak #

Tampilan tabel normal psql menjadi sulit dibaca ketika barisnya lebar — kolom-kolom saling berebut ruang. Meta-command \x menggantinya dengan format expanded: setiap baris data ditampilkan sebagai satu record tersendiri, satu kolom per baris:

-- Aktifkan tampilan expanded: satu baris data ditampilkan per record
\x on

SELECT id, nama, email, kota
FROM pelanggan
ORDER BY id;

-- Kembali ke tampilan tabel normal
\x off

SELECT id, nama
FROM pelanggan
ORDER BY id;

Output yang Dihasilkan:

text
Expanded display is on.
-[ RECORD 1 ]-----------
id    | 1
nama  | Budi Santoso
email | [email protected]
kota  | Jakarta
-[ RECORD 2 ]-----------
id    | 2
nama  | Siti Rahayu
email | [email protected]
kota  | Bandung
-[ RECORD 3 ]-----------
id    | 3
nama  | Andi Wijaya
email | [email protected]
kota  | Surabaya

Expanded display is off.
 id |     nama     
----+--------------
  1 | Budi Santoso
  2 | Siti Rahayu
  3 | Andi Wijaya
(3 rows)

Pada hasil pertama, tiga baris data tampil sebagai RECORD 1, RECORD 2, dan RECORD 3 — jauh lebih nyaman dibaca ketika tabel punya belasan kolom. Meta-command \x off mengembalikan tampilan normal, seperti hasil kedua. Dalam mode interaktif, cukup ketik \x untuk berganti bolak-balik tanpa argumen.

Meta-command sejenis yang patut dikenal: \timing menampilkan lama eksekusi setiap query dalam milidetik. Nilainya berguna saat mengukur performa, tetapi berbeda-beda antar mesin dan antar percobaan, sehingga tidak kita tampilkan sebagai output contoh di sini.

Menjalankan File dan Perintah Tunggal #

Mode interaktif enak untuk eksplorasi, tetapi pekerjaan sehari-hari lebih sering berbentuk file SQL yang dijalankan ulang: skrip migrasi, seed data, atau latihan seperti contoh-contoh di course ini. Tiga flag psql menjadi tulang punggung alur kerja tersebut:

FlagFungsi
-f nama_file.sqlMenjalankan seluruh isi file lalu keluar
-c "perintah SQL"Menjalankan satu perintah (atau meta-command) lalu keluar
-XTidak membaca file startup .psqlrc milik user — menjaga hasil tetap konsisten
-d nama_databaseMemilih database tujuan
-h host -p port -U userMenimpa host, port, dan user koneksi

Flag -h, -p, dan -U akan kita bedah tuntas di chapter Koneksi ke Database Server. File SQL pendek berikut menjadi bahan latihan untuk dua flag pertama:

SELECT id, nama, kota
FROM pelanggan
ORDER BY id;

Output yang Dihasilkan:

text
 id |     nama     |   kota   
----+--------------+----------
  1 | Budi Santoso | Jakarta
  2 | Siti Rahayu  | Bandung
  3 | Andi Wijaya  | Surabaya
(3 rows)

Skrip berikut memakai kedua flag sekaligus — file di atas dijalankan dengan -f, lalu satu query hitung dijalankan dengan -c:

bash psql-flag.sh
# -f: jalankan seluruh file SQL sekaligus
psql -X -f tampilkan-pelanggan.sql

# -c: jalankan satu perintah SQL tanpa membuka mode interaktif
psql -X -c "SELECT count(*) AS jumlah_pelanggan FROM pelanggan;"

Output yang Dihasilkan:

text
 id |     nama     |   kota   
----+--------------+----------
  1 | Budi Santoso | Jakarta
  2 | Siti Rahayu  | Bandung
  3 | Andi Wijaya  | Surabaya
(3 rows)

 jumlah_pelanggan 
------------------
                3
(1 row)

Perhatikan bahwa skrip itu dijalankan dari direktori yang sama dengan file SQL-nya, sehingga psql -X -f tampilkan-pelanggan.sql cukup memakai nama file polos. Dari dalam mode interaktif, tugas yang sama dikerjakan meta-command \i nama_file.sql — file dicari relatif terhadap direktori tempat psql dijalankan.

ON_ERROR_STOP: Berhenti di Perintah Pertama yang Gagal #

Saat menjalankan file berisi banyak perintah, perilaku bawaan psql cukup longgar: bila satu perintah gagal, psql hanya mencatat error lalu melanjutkan ke baris berikutnya. Untuk skrip penting, perilaku ini berbahaya — setengah skrip bisa berhasil diterapkan tanpa kita sadari. Flag -v ON_ERROR_STOP=1 mengubahnya: psql berhenti di perintah pertama yang gagal.

File berikut sengaja berisi perintah pembagian nol yang pasti gagal:

sql bagi-nol.sql
SELECT 1/0;

SELECT 'baris kedua tidak pernah dieksekusi';

Output yang Dihasilkan:

text
psql:bagi-nol.sql:1: ERROR:  division by zero

Pesan error pada output menunjukkan lokasi kegagalan: file bagi-nol.sql baris pertama, ERROR: division by zero. Perintah SELECT kedua tidak pernah dieksekusi — seluruh file contoh di course ini memang dijalankan dengan ON_ERROR_STOP aktif, dan exit code psql 3 menjadi penanda bahwa kegagalan berasal dari perintah SQL, bukan dari koneksi.

Dengan psql di tangan, semakin banyak pekerjaan bisa diselesaikan tanpa meninggalkan terminal. Namun ada kalanya kita menginginkan tampilan grafis — menjelajahi struktur database dengan klik kanan atau mengedit data dalam bentuk tabel. Untuk itu PostgreSQL punya pgAdmin, alat yang kita jelajahi di chapter berikutnya.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

bagi-nol.sql

Unduh berkas
sql
SELECT 1/0;

SELECT 'baris kedua tidak pernah dieksekusi';

buat-tabel.sql

Unduh berkas
sql
CREATE TABLE pelanggan (
    id    integer PRIMARY KEY,
    nama  text NOT NULL,
    email text NOT NULL,
    kota  text NOT NULL
);

INSERT INTO pelanggan (id, nama, email, kota) VALUES
    (1, 'Budi Santoso', '[email protected]', 'Jakarta'),
    (2, 'Siti Rahayu', '[email protected]', 'Bandung'),
    (3, 'Andi Wijaya', '[email protected]', 'Surabaya');

SELECT id, nama, email, kota
FROM pelanggan
ORDER BY id;

format-tampilan.sql

Unduh berkas
sql
-- Aktifkan tampilan expanded: satu baris data ditampilkan per record
\x on

SELECT id, nama, email, kota
FROM pelanggan
ORDER BY id;

-- Kembali ke tampilan tabel normal
\x off

SELECT id, nama
FROM pelanggan
ORDER BY id;

meta-command.sql

Unduh berkas
sql
-- Ringkasan koneksi yang sedang aktif
\conninfo

-- Daftar tabel di schema pencarian saat ini
\dt

-- Struktur tabel pelanggan
\d pelanggan

-- Daftar schema di database ini
\dn

-- Daftar database yang namanya dimulai dengan "post"
\l post*

meta-roles.sql

Unduh berkas
sql
-- Daftar role di cluster; isinya berbeda-beda antar lingkungan
\du

psql-flag.sh

Unduh berkas
bash
# -f: jalankan seluruh file SQL sekaligus
psql -X -f tampilkan-pelanggan.sql

# -c: jalankan satu perintah SQL tanpa membuka mode interaktif
psql -X -c "SELECT count(*) AS jumlah_pelanggan FROM pelanggan;"

tampilkan-pelanggan.sql

Unduh berkas
sql
SELECT id, nama, kota
FROM pelanggan
ORDER BY id;