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ı?

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öntem | Dosyanın içeriği | json.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

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
- Oku:
open(..., "r", encoding="utf-8")ile dosyayı aç,json.load(f)ile içindeki listeyi Python nesnesine çevir. - Ekle: Yeni kaydı bellekteki listeye ekle. Bu adımda dosyaya dokunulmaz.
- 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ışı karakterleru00fcgibi kaçış dizilerine çevrilir.Falseverince "ü", "ş", "ğ" 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.