PostgreSQL relation does not exist hatası, sorguda kullanılan tablo veya benzeri nesnenin mevcut bağlantı bağlamında bulunamadığını gösterir. Çözüm için önce doğru veritabanına bağlandığını, ardından nesnenin doğru şema ve adla mevcut olduğunu kontrol etmelisin. Yanlış veritabanı, farklı bir şema, büyük harf kullanımı ve bağlantı ayarları bu hatanın yaygın nedenleri arasındadır.
Teşhis sırasında tabloyu yeniden oluşturmak ya da veri silen komutlar çalıştırmak yerine bağlantı bilgilerini ve nesne adını adım adım incelemek daha güvenlidir.
PostgreSQL relation hatası ne anlama gelir?
PostgreSQL'de relation terimi, sorgularda başvurulabilen tablo, görünüm, materialized view, indeks, sequence ve foreign table gibi veritabanı nesnelerini kapsar. Bu nedenle hata mesajında relation yazması, sorunun yalnızca klasik bir tabloda ortaya çıkacağı anlamına gelmez.
Örneğin şu sorgu, PostgreSQL'in mevcut bağlantı bağlamında customers adlı nesneyi bulamadığını gösteren bir hata üretebilir:
SELECT * FROM customers;
Hata metni genellikle ERROR: relation "customers" does not exist biçimindedir. PostgreSQL hata kodları içinde bu durum 42P01, yani tanımlanmamış tablo koşuluyla ilişkilendirilir. Ayrıntılar için PostgreSQL hata kodları belgelerine bakabilirsin.
Buradaki “bulunamıyor” ifadesi her zaman nesnenin hiç oluşturulmadığını göstermez. Sorgu başka bir veritabanına bağlı olabilir, nesne farklı bir şemada bulunabilir veya PostgreSQL sorgudaki adı oluşturulurken kullanılan adla eşleştiremeyebilir. Özellikle tablo adında büyük harf kullanıldıysa, tırnakların eksik ya da tutarsız olması da aynı hataya yol açabilir.
Örneğin public.customers ile sales.customers aynı veritabanında bulunan iki farklı nesnedir. Sorguda yalnızca customers yazıldığında PostgreSQL, geçerli search_path ayarına göre arama yapar. Bu ayarda ilgili şema bulunmuyorsa tablo mevcut olsa bile sorgu nesneyi bulamayabilir.
Önce doğru veritabanına ve tabloya bağlı olduğunu kontrol et

İlk kontrol, sorguyu çalıştırdığın oturumun doğru veritabanı ve sunucuya bağlı olup olmadığını doğrulamaktır. psql içinde conninfo komutu mevcut bağlantı hakkında bilgi verir; böylece veritabanı, kullanıcı ve bağlantı adresini sorgunun çalışması gereken ortamla karşılaştırabilirsin.
conninfo
dt
dt public.*
dt komutu, mevcut veritabanında erişilebilen kullanıcı tablolarını listeler. dt public.* biçimi ise tablo aramasını public şemasıyla sınırlar. Bu komutların psql içindeki kullanım biçimleri PostgreSQL psql belgelerinde açıklanır.
- Bağlantıyı kontrol et:
conninfoçıktısındaki veritabanı, sunucu ve kullanıcı bilgilerini incele. - Gerekirse doğru veritabanına geç: psql içinde
c proje_veritabanikomutunu kullan. Kullanıcıyı da belirtmen gerekiyorsac proje_veritabani kullanici_adiyazabilirsin. - Tabloyu listele:
dtile tabloları, belirli bir şemayı kontrol etmek içindt sema_adi.*komutunu çalıştır. - Adı karşılaştır: Listede gördüğün tablo adını sorgudaki adla harf, alt çizgi ve tırnak kullanımı bakımından karşılaştır.
c komutu yeni bir PostgreSQL bağlantısı kurar. Örneğin:
c okul_projesi
Bu komuttan sonra aynı sorguyu yeniden denemeden önce conninfo ve dt ile yeni bağlantının ve tablo listesinin doğru olduğunu kontrol et. Tablo listede görünmüyorsa hemen yeniden oluşturma; önce tablonun başka bir şemada bulunup bulunmadığını ve oluşturma işleminin gerçekten bu veritabanında çalıştırılıp çalıştırılmadığını incele. Böylece mevcut veriler üzerinde gereksiz bir değişiklik yapmadan sorunun bağlantıdan mı, nesnenin adından mı kaynaklandığını ayırabilirsin.
Büyük harfli tablo adlarında tırnakları tutarlı kullan

PostgreSQL, tırnaksız yazılan nesne adlarını küçük harfe çevirir. Bu nedenle CREATE TABLE "Ogrenciler" ile oluşturulan tablo adı büyük O harfini korur; SELECT * FROM Ogrenciler ise ogrenciler tablosuna erişmeye çalışır. İki ad eşleşmediği için sorgu tabloyu bulamaz. Tırnaklı adların büyük-küçük harfe duyarlı, tırnaksız adların ise küçük harfe dönüştürüldüğünü PostgreSQL’in tanımlayıcı kuralları açıklar.
SELECT * FROM "Ogrenciler";
Tablo gerçekten "Ogrenciler" adıyla oluşturulduysa bu sorgu doğru ada erişir. Tırnakların içinde büyük O harfi bulunduğu için adı yazarken büyük-küçük harfleri aynı tutmalısın.
SELECT * FROM ogrenciler;
Bu sorgu, tablo küçük harfli ogrenciler adıyla oluşturulduysa çalışır. Oluşturma sırasında ad tırnaksız yazıldığında PostgreSQL onu küçük harfe dönüştürür. Mevcut tabloyu yeniden oluşturmak yerine, sorgudaki adı tablonun oluşturulduğu biçimle eşleştir.
Şema adını ve search_path değerini incele
Şema, veritabanındaki tabloları ve diğer nesneleri ad alanları altında gruplandırır. search_path ise şema adı yazılmadan kullanılan bir tablo adının hangi şemalarda aranacağını belirler. PostgreSQL’in şemalarla ilgili açıklaması, arama yolunda bulunmayan bir şemadaki tabloya tam adıyla erişilebileceğini belirtir.
Örneğin tablo okul şemasındaysa ve bu şema etkin arama yolunda yer almıyorsa aşağıdaki sorgu tabloyu bulamayabilir:
SELECT * FROM ogrenciler;
Şema adını tablo adının önüne ekleyerek arama yoluna bağlı kalmadan doğru nesneyi belirtebilirsin:
SELECT * FROM okul.ogrenciler;
Bu biçim, okul şemasındaki küçük harfli ogrenciler tablosuna erişir. Arama yolunu incelemek için SHOW search_path; komutunu çalıştırabilirsin. Sorgudaki tablo adı doğru görünüyorsa, tabloyu hangi şemada oluşturduğunu ve o şemanın arama yolunda bulunup bulunmadığını kontrol et.
Uygulama bağlantısını veri kaybına yol açmadan teşhis et
Tablo psql içinde görünmesine rağmen uygulama “relation does not exist” hatası veriyorsa uygulama farklı bir veritabanına, farklı bir şemaya veya farklı bir tablo adına bağlanıyor olabilir. Aynı PostgreSQL sunucusunda birden fazla veritabanı bulunması, bağlantı adresindeki küçük bir farkın farklı bir veri alanına yönlendirmesine neden olabilir.
Önce psql bağlantısında hangi veritabanının ve kullanıcının aktif olduğunu kontrol et. Ardından tabloyu ve arama yolunu görüntüleyerek uygulamanın bağlantı ayarlarıyla karşılaştır:
conninfo
dt
SELECT current_database(), current_schema(), current_setting('search_path');
conninfo aktif bağlantının temel bilgilerini, dt ise geçerli arama yolunda görünür tabloları gösterir. Bu komutların ayrıntıları için PostgreSQL psql belgelerine bakabilirsin.
- Uygulamanın bağlantı ayarındaki veritabanı adı ile
conninfoçıktısını karşılaştır. - Sunucu adresi ve port bilgilerinin psql bağlantısıyla aynı olduğundan emin ol.
- Sorguda kullanılan tablo adını,
dtçıktısındaki adla harf büyüklüğü ve şema bilgisi bakımından karşılaştır. - Tablo varsayılan şemada değilse sorguda şema adının kullanıldığını veya
search_pathdeğerinin doğru ayarlandığını kontrol et.
Bu kontroller tamamlanmadan tabloyu silip yeniden oluşturma yoluna gitme. Yanlış veritabanında işlem yapmak mevcut veriyi riske atabilir; ayrıca yeni oluşturulan boş tablo, uygulamanın doğru veri kaynağına bağlandığı anlamına gelmez. Güvenli sıra, önce bağlantıyı doğrulamak, sonra veritabanını ve tablo adını karşılaştırmak, ardından şema ve search_path değerini incelemektir.
Sık Sorulan Sorular
PostgreSQL’de relation yalnızca tablo anlamına mı gelir?
PostgreSQL’de relation çoğu durumda tabloyu ifade eder, ancak görünüm, materialized view, sequence ve foreign table gibi nesneler de bu kapsamda anılabilir. “relation does not exist” hatası, sorguda belirtilen nesnenin mevcut bağlantı ve şema arama kurallarıyla bulunamadığını anlatır.
psql içinde bağlı olduğum veritabanını ve tabloları nasıl kontrol ederim?
Bağlı olduğun veritabanını conninfo komutuyla, görünür tabloları ise dt komutuyla kontrol edebilirsin. Şema ve arama yolunu incelemek için SELECT current_database(), current_schema(), current_setting('search_path'); sorgusunu çalıştırabilirsin.
Tabloyu yeniden oluşturmak relation hatasını çözer mi?
Tabloyu yeniden oluşturmak, özellikle uygulama yanlış veritabanına bağlıysa, gerçek sorunu çözmez ve mevcut verinin kaybolmasına veya boş bir tablonun kullanılmasına yol açabilir. Önce bağlantı, veritabanı, tablo adı ve şema bilgilerini güvenli sorgularla doğrulamak gerekir.
“relation does not exist” hatasında en güvenli yaklaşım, veri üzerinde değişiklik yapmadan bağlantı bilgilerini ve nesnenin bulunduğu konumu adım adım karşılaştırmaktır.