İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

Python JSON Dosyasına Birden Fazla Kayıt Nasıl Eklenir? Örnekle

python-json-dosyasina-birden-fazla-kayit-ekleme
Bu yazıda neler var?
  1. Kayıtlar Neden Tek Bir Liste İçinde Durmalı?
  2. Art Arda dump() Çağırmak ya da "a" Kipi Dosyada Ne Bırakır?
  3. Doğru Yöntem: Oku, Listeye Ekle, Tek Seferde Yaz
  4. append() mi extend() mi? Birden Fazla Kaydı Tek Hamlede Eklemek

Python'da JSON dosyasına birden fazla kayıt eklemenin güvenli yolu, kayıtları dosyada tek bir liste olarak tutmaktır. Dosyayı json.load() ile okursun, yeni kaydı listeye eklersin, listenin tamamını json.dump() ile tek seferde yeniden yazarsın. Dosyanın sonuna ayrı ayrı nesne eklemek ilk bakışta mantıklı görünür, ama dosyayı bir sonraki okuyuşta hata verir. Aşağıda bunun nedenini somut bir çıktıyla görecek, çözümü de adım adım kuracaksın.

Kayıtlar Neden Tek Bir Liste İçinde Durmalı?

Kayıtlar Neden Tek Bir Liste İçinde Durmalı?

Birden fazla kaydı taşıyan bir JSON dosyasının en güvenli biçimi köşeli parantezli bir listedir. Her kayıt bu listenin bir öğesidir ve Python'daki karşılığı bir sözlüktür. İki öğrenci kaydı şöyle görünür:

[{"ad": "Ece", "yas": 15}, {"ad": "Can", "yas": 16}]

Bu satırda üç şey var: dıştaki [ ] tüm kayıtları saran listeyi, içteki her { } tek bir kaydı (sözlüğü), kayıtlar arasındaki virgül ise liste öğelerinin ayrımını gösterir. Python'ın json modülü dosyanın tamamından tek bir JSON değeri bekler. Bu değer bir liste olduğunda, kaç kayıt olursa olsun dosya tek parça kalır.

Dosyayı okuyunca da Python'da tanıdık bir yapıyla karşılaşırsın:

import json

with open("ogrenciler.json", encoding="utf-8") as dosya:
    kayitlar = json.load(dosya)

print(type(kayitlar), len(kayitlar))
print(kayitlar[1]["ad"])

Beklenen çıktı:

<class 'list'> 2
Can

Gelen veri sıradan bir liste olduğu için len(), indeksleme ve döngü gibi bildiğin her şey çalışır. Liste ve sözlük kavramlarında eksik hissediyorsan, ücretsiz Sıfırdan Temel Python video eğitimi bu temeli kendi hızında pekiştirmene yardımcı olabilir.

Art Arda dump() Çağırmak ya da "a" Kipi Dosyada Ne Bırakır?

Yeni kaydı dosyanın sonuna eklemek doğal bir fikirdir. Metin dosyalarında bu iş "a" (append) kipiyle yapılır ve çoğu zaman sorunsuz çalışır. JSON'da ise iş biraz farklıdır. Önce iki yöntemi deneyelim. Demoda yalnızca ASCII karakterli adlar kullanıyorum, çünkü Python'ın json.dump() varsayılan olarak ASCII dışı karakterleri uXXXX biçiminde yazar ve bu, dosya içeriğini okumayı zorlaştırır.

Yöntem 1: Art arda json.dump()

import json

kayitlar = [{"ad": "Ece", "yas": 15}, {"ad": "Can", "yas": 16}]

with open("ogrenciler.json", "w", encoding="utf-8") as dosya:
    for kayit in kayitlar:
        json.dump(kayit, dosya)

Yöntem 2: "a" kipiyle ekleme

import json

with open("ogrenciler.json", "a", encoding="utf-8") as dosya:
    json.dump({"ad": "Ece", "yas": 15}, dosya)

with open("ogrenciler.json", "a", encoding="utf-8") as dosya:
    json.dump({"ad": "Can", "yas": 16}, dosya)

Dosya daha önce yoksa "a" kipi onu oluşturur. İki yöntem de dosyada aynı içeriği bırakır:

{"ad": "Ece", "yas": 15}{"ad": "Can", "yas": 16}

Aralarında köşeli parantez de virgül de yok. Yani karşında bir liste değil, yan yana yapışmış iki bağımsız nesne var. json.dump() yalnızca verdiğin değeri yazar; dosyada daha önce ne olduğunu bilmez, araya ayırıcı koymaz.

Neden hata verir?

Burada kural net: JSON dosyası, art arda eklenmiş bağımsız nesnelerden değil, geçerli tek bir JSON değeri içeren yapıdan oluşmalıdır. Yukarıdaki dosyada her nesne tek başına geçerlidir, ama dosyanın bütünü tek bir değer olmaz. Bu dosyayı okumayı denediğinde şunu görürsün:

import json

with open("ogrenciler.json", encoding="utf-8") as dosya:
    kayitlar = json.load(dosya)
json.decoder.JSONDecodeError: Extra data: line 1 column 25 (char 24)

Konum bilgisi örnek içerikten hesaplanabilir. İlk nesne {"ad": "Ece", "yas": 15} tam 24 karakterdir ve 0 ile 23. karakterler arasında yer alır. Python bu ilk nesneyi sorunsuz okur, 24. karakterde (sıfırdan sayıldığında) ikinci bir { görünce "fazladan veri" der. Dosya tek satır olduğu için satır 1'dir. Sütun numarası ise karakter konumunun bir fazlasıdır: 25. Hatadaki "Extra data" ifadesi bu yüzden "ilk değerden sonra bir şey daha var" demektir. Hata mesajı dosyanın bozulduğunu değil, ilk geçerli değerden sonra artık veri kaldığını söyler.

Üç yöntemin yan yana karşılaştırması

YöntemDosyanın içeriğijson.load() sonucu
Art arda dump(){"ad": "Ece", "yas": 15}{"ad": "Can", "yas": 16}JSONDecodeError: Extra data: line 1 column 25 (char 24)
"a" kipiyle ekleme{"ad": "Ece", "yas": 15}{"ad": "Can", "yas": 16}JSONDecodeError: Extra data: line 1 column 25 (char 24)
Listeyi okuyup yeniden yazma[{"ad": "Ece", "yas": 15}, {"ad": "Can", "yas": 16}]Sorunsuz: [{'ad': 'Ece', 'yas': 15}, {'ad': 'Can', 'yas': 16}] (çözüm sonraki bölümde)

İlk iki yöntemi denemek olağan bir öğrenme adımıdır. Metin dosyasında işe yarayan "sonuna ekle" mantığını JSON'a taşımak herkesin aklına gelir. JSON'un dosya düzeyinde bir yapı olduğunu bir kez gördükten sonra, doğru yöntem de kendiliğinden anlam kazanır.

Doğru Yöntem: Oku, Listeye Ekle, Tek Seferde Yaz

Doğru Yöntem: Oku, Listeye Ekle, Tek Seferde Yaz

Güvenli akış üç adımdır: dosyayı oku, Python listesine yeni kaydı ekle, listenin tamamını dosyaya geri yaz. Dosyaya doğrudan ekleme yapmak yerine her seferinde bellekteki listeyi güncelleyip bütün olarak yazarsın. Böylece dosyanın içinde her zaman tek bir geçerli JSON değeri bulunur.

Üç adımın arkasındaki mantık

  1. Oku: open(..., "r", encoding="utf-8") ile dosyayı aç, json.load(f) ile içindeki listeyi Python nesnesine çevir.
  2. Ekle: Yeni kaydı bellekteki listeye ekle. Bu adımda dosyaya dokunulmaz.
  3. Yaz: open(..., "w", encoding="utf-8") ile dosyayı yeniden aç, json.dump(liste, f, indent=2, ensure_ascii=False) ile listenin tamamını yaz.

Sıra önemlidir. "w" kipi dosyayı açtığın anda içeriğini siler. Önce okumazsan eski kayıtlar yazma adımına varmadan kaybolur. Bu yüzden okuma ve yazma için dosyayı iki ayrı with bloğunda açarız.

Parametrelerin rolleri de şöyledir:

  • indent=2: Çıktıyı girintili, satır satır yazar. Dosyayı elle açtığında okunabilir olur. Vermezsen her şey tek satıra sığar.
  • ensure_ascii=False: Varsayılanda ASCII dışı karakterler u00fc gibi kaçış dizilerine çevrilir. False verince "ü", "ş", "ğ" dosyada olduğu gibi görünür.
  • encoding="utf-8": open() için kodlama belirtmezsen varsayılan platforma bağlıdır. Yani aynı kod başka bir bilgisayarda Türkçe karakterleri farklı yazıp okuyabilir. Hem okurken hem yazarken "utf-8" belirtmek bu belirsizliği ortadan kaldırır.

Çalışan örnek: kayit_ekle() fonksiyonu

import json
import os

DOSYA = "kayitlar.json"

def kayit_ekle(yeni_kayit):
    if os.path.exists(DOSYA):
        with open(DOSYA, "r", encoding="utf-8") as f:
            kayitlar = json.load(f)
    else:
        kayitlar = []

    kayitlar.append(yeni_kayit)

    with open(DOSYA, "w", encoding="utf-8") as f:
        json.dump(kayitlar, f, indent=2, ensure_ascii=False)

    return len(kayitlar)

toplam = kayit_ekle({"ad": "Gülşen", "gorev": "Rapor hazırla"})
print("Toplam kayıt:", toplam)

Dosya henüz yoksa fonksiyon boş bir liste ile başlar. Bu yüzden ilk çalıştırmada hata almazsın.

1. çalıştırmadan sonra ekrana basılan:

Toplam kayıt: 1

kayitlar.json dosyasının tam içeriği:

[
  {
    "ad": "Gülşen",
    "gorev": "Rapor hazırla"
  }
]

Şimdi programdaki son iki satırı şöyle değiştirip ikinci kez çalıştır:

toplam = kayit_ekle({"ad": "Şükrü", "gorev": "Sunumu gönder"})
print("Toplam kayıt:", toplam)

2. çalıştırmadan sonra ekrana basılan:

Toplam kayıt: 2

kayitlar.json dosyasının tam içeriği:

[
  {
    "ad": "Gülşen",
    "gorev": "Rapor hazırla"
  },
  {
    "ad": "Şükrü",
    "gorev": "Sunumu gönder"
  }
]

Eski kayıt yerinde duruyor, yeni kayıt listenin sonuna eklenmiş ve dosya hâlâ tek bir köşeli parantez çiftiyle başlayıp bitiyor. Türkçe karakterler de kaçış dizisine dönüşmeden okunuyor.

append() mi extend() mi? Birden Fazla Kaydı Tek Hamlede Eklemek

Elinde birden fazla yeni kayıt varsa extend() doğru araçtır. append() verdiğin şeyi tek bir öğe olarak ekler; ona bir liste verirsen o liste, ana listenin içine iç içe bir öğe olarak girer. extend() ise verdiğin listenin öğelerini tek tek ana listeye ekler.

Farkı aynı iki yeni kayıtla görelim:

mevcut = [{"ad": "Gülşen"}]
yeni = [{"ad": "Şükrü"}, {"ad": "Çağrı"}]

a = mevcut.copy()
a.append(yeni)
print("append:", a)

b = mevcut.copy()
b.extend(yeni)
print("extend:", b)

Beklenen çıktı:

append: [{'ad': 'Gülşen'}, [{'ad': 'Şükrü'}, {'ad': 'Çağrı'}]]
extend: [{'ad': 'Gülşen'}, {'ad': 'Şükrü'}, {'ad': 'Çağrı'}]

İlk satırda ikinci öğe bir sözlük değil, içinde iki sözlük bulunan bir listedir. Bu hâliyle json.dump() ile yazarsan dosyada iç içe bir dizi oluşur ve her kaydı okurken beklediğin yapıyı bulamazsın. İkinci satırda ise tüm kayıtlar aynı düzeyde, düz bir listede durur.

Karar ölçütü

  • Tek kayıt ekliyorsan: append(kayit) yeterlidir.
  • Birden fazla kayıt ekliyorsan: kayıtları bir listede topla ve extend(kayitlar) kullan.

Önceki bölümdeki fonksiyonu çoklu kayıt için uyarlamak istersen yalnızca ekleme satırı değişir: kayitlar.extend(yeni_kayitlar). Okuma ve yazma adımları aynı kalır. Birden fazla kayıt da olsa dosyaya yalnızca bir kez yazarsın: önce extend() ile bellekteki listeyi tamamla, sonra tek bir json.dump() çağrısı yap. Her kayıt için ayrı ayrı yazmaya gerek yoktur.

Özetle, JSON dosyasına kayıt eklemek aslında bir liste güncelleme işidir: oku, listeyi büyüt, bütün olarak geri yaz. Bu düzeni oturttuktan sonra görev listesi, not defteri ya da küçük bir kullanıcı kaydı gibi projelerde dosyanın bozulmasından endişe etmeden ilerleyebilirsin.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara