Menu

SQLite CSV Import: .import Komutuyla Veri Yükleme

SQLite'a CSV dosyası nasıl aktarılır? .import komutuyla başlık satırı, mevcut tablolar, özel ayraçlar ve sık karşılaşılan hatalar üzerinden adım adım anlatım.

Bu sayfada çalıştırılabilir editörler var — düzenle, çalıştır ve sonucu anında gör.

CSV İçe Aktarma SQL'de Değil, CLI'da Yaşar

SQLite'ın SQL söz diziminde IMPORT diye bir komut yoktur. CSV yükleme işi tamamen sqlite3 komut satırı kabuğuna ait bir özelliktir; yani .import adında bir nokta komutuyla yapılır. MySQL'in LOAD DATA INFILE komutundan veya Postgres'in COPY komutundan geliyorsanız bu zihinsel ayrım önemli: o komutlar sunucu tarafında çalışır, ama .import istemci aracının kendisinin yaptığı bir iştir — dosyayı okur ve arka planda INSERT ifadelerini sizin yerinize çalıştırır.

Yani bu sayfadaki her şey, sqlite3 kabuğunun içinde olduğunuzu varsayar:

sqlite3 mydata.db

Eğer CSV'yi uygulama kodundan içeri almanız gerekiyorsa — Python, Node, Go gibi — CSV'yi kendi dilinizde okuyup parametreli INSERT ifadeleri kullanırsınız. Bu yaklaşımı uygulama entegrasyonu bölümünde ele alacağız. Burada odak noktamız CLI.

En Basit Haliyle .import Komutu

En kısa yol şu: SQLite'a dosyanın CSV olduğunu söyleyin, ardından .import komutunu dosya yoluna ve hedef tablo adına yönlendirin.

.mode csv
.import people.csv people

people tablosunun var olup olmamasına göre iki farklı senaryo yaşanır:

  • Tablo yoksa — SQLite tabloyu kendisi oluşturur ve CSV'nin ilk satırını sütun adları olarak kullanır. Tüm sütunlar TEXT tipinde olur.
  • Tablo zaten varsa — SQLite dosyadaki her satırı veri olarak ekler. Başlık satırı varsa, o da bir veri satırı olarak tabloya girer.

İşte çoğu kişinin ilk denemede tökezlediği nokta tam olarak bu ikinci durum. CSV dosyanızda başlık satırı varsa ve tablo da önceden oluşturulmuşsa, başlık satırını açıkça atlamanız gerekir.

Mevcut Tabloya CSV Aktarırken Başlık Satırını Atlama

.import komutuna ilk N satırı yok saymasını söylemek için --skip 1 parametresini kullanın:

CREATE TABLE people (
    name TEXT,
    age  INTEGER,
    city TEXT
);

.import --csv --skip 1 people.csv people

--csv, sadece bu komut için geçerli olan .mode csv ayarının kısa yoludur; yani modu ayrıca ayarlamak zorunda kalmazsın. --skip 1 ile başlık satırını atlarsınız. Geriye kalan satırlar da people tablosuna kolon sırasına göre eklenir.

İçe aktarma sonrası hızlı bir kontrol:

SELECT count(*) FROM people;
SELECT * FROM people LIMIT 5;

Dosyadaki sütun sırası, tablodaki sütun sırasıyla birebir aynı olmalı. Başlık adına göre eşleme diye bir şey yok — .import basitçe N'inci alanı N'inci sütuna yerleştirir.

Tabloyu SQLite'a oluşturtmak

Hızlıca bir şeyleri kurcalamak istediğinde en pratik yol, CREATE TABLE adımını tamamen atlayıp tabloyu başlık satırından .import komutuna oluşturtmaktır:

.mode csv
.import sales.csv sales

.schema sales

.schema sales komutu çalıştırıldığında şuna benzer bir çıktı görürsünüz:

CREATE TABLE sales(
  "order_id" TEXT,
  "amount" TEXT,
  "ordered_at" TEXT
);

Dikkat ederseniz tüm sütunlar TEXT türünde. Bu bilinçli bir tercih — .import komutu tür çıkarımı yapmaya çalışmaz. Eğer amount alanını gerçek bir sayı, ordered_at alanını da düzgün bir zaman damgası olarak istiyorsanız, tabloyu önce kendiniz doğru türlerle oluşturup ardından --skip 1 ile içe aktarın. SQLite'ın type affinity özelliği, sayısal string değerleri ekleme sırasında integer ve real türlerine kendiliğinden dönüştürür.

Özel ayraçlar: TSV, pipe, noktalı virgül

.mode csv virgülü ayraç olarak kullanır. Tab ile ayrılmış dosyalar için modu değiştirmeniz yeterli:

.mode tabs
.import data.tsv events

Farklı ayırıcılar için, modu seçtikten sonra .separator komutunu kullanın:

.mode csv
.separator "|"
.import pipe_data.txt events

Şunu bilmekte fayda var: .mode csv RFC 4180 alıntı kurallarına uyar — yani içinde virgül veya satır sonu geçen alanlar, " ile düzgün biçimde alıntılandığı sürece sorunsuz çalışır. .mode tabs ise alıntılama desteği olmayan, sadece karaktere göre bölen daha basit bir moddur. Eğer dosyanızda ayraç içeren alıntılı alanlar varsa, .mode csv modunda kalıp ayraç karakterini değiştirmeniz daha doğru olur.

Gerçek Bir Örnek Üzerinden CSV Aktarma

Diyelim ki elimizdeki orders.csv dosyası şöyle görünüyor:

order_id,customer,amount,ordered_at
1001,Ada,49.99,2026-01-12
1002,Boris,12.50,2026-01-13
1003,"Chen, Wei",199.00,2026-01-14
  1. satırda tırnak içinde virgül geçen bir alan olduğuna dikkat edin. Tam oturum şöyle:

Gerçek bir shell'de INSERT bloğunun yerini tek bir .import --csv --skip 1 orders.csv orders komutu alır. CSV modu tırnakları koruduğu için "Chen, Wei" alanı bozulmadan gelir. Sütun tipleri sayesinde amount gerçek bir sayı, order_id ise tam sayı olarak kaydedilir.

CSV Aktarımını Transaction İçine Almak

.import her satır için ayrı bir INSERT çalıştırır. Birkaç bin satır için sorun yok, ama milyonluk verilerde SQLite her satırdan sonra commit yaptığı için iş çekilmez bir hâl alır. Çözüm, tüm aktarımı bir transaction'a sarmak:

BEGIN;
.import --csv --skip 1 big_file.csv events
COMMIT;

Tek bir değişiklikle dakikalar süren bir import işlemi birkaç saniyeye iner. İşlem ortasında bir şeyler ters giderse ROLLBACK yarıda kalan yüklemeyi geri alır; bu da tekrar denemelerde işinize yarar.

Daha da hızlandırmak isterseniz import'tan önce index'leri kaldırıp sonradan yeniden oluşturabilirsiniz — her satır için index güncellemesi ciddi yük bindiriyor.

Sık Karşılaşılan Hatalar ve Çözümleri

Error: expected N columns but found M — bir satırdaki alan sayısı tabloyla uyuşmuyor. Genelde sebebi şudur:

  • Tırnaksız bir alanın içinde kaçak bir virgül vardır. Dosyayı düzgün CSV tırnaklamasıyla yeniden export edin ya da .mode tabs yerine .mode csv (RFC 4180) kullanın.
  • Dosyanın sonunda boş bir satır kalmıştır. Dosyayı düzenleyin veya --skip ile yaratıcı olun.
  • Tabloda CSV'den daha fazla kolon vardır. Ya eksik kolonları dosyaya ekleyin ya da uygun şemada bir ara (staging) tablosuna yükleyip oradan asıl tabloya kopyalayın.

Başlık satırı veri olarak görünüyor — mevcut bir tabloya yazarken --skip 1 koymayı unutmuşsunuzdur. O satırı silip (DELETE FROM t WHERE rowid = 1) flag ile yeniden çalıştırın.

Sayılar string olarak saklanmış — tabloyu .import komutuna oluşturttuğunuzda her kolon TEXT olur. Tabloyu silin, INTEGER/REAL kolonlarıyla elle tanımlayın ve tekrar import edin.

Error: no such file — yol, veritabanı dosyasına göre değil, sqlite3'ü başlattığınız dizine göre çözülür. Mutlak yol kullanın ya da shell'i açmadan önce doğru dizine cd ile geçin.

CLI hatalarda satır numarasını yazdırır; büyük dosyalarda sorunlu satırı bulmanın en hızlı yolu budur.

Kısa Bir Özet

  • .import bir SQL komutu değil, CLI'ye özel bir nokta komutudur. sqlite3 shell'i içinde çalıştırın.
  • Tırnakların doğru yorumlanması için --csv, başlık satırını atlamak için --skip 1 kullanın.
  • Tablo yoksa .import başlık satırına bakıp tabloyu kendisi oluşturur — ama tüm kolonlar TEXT olur. Doğru tipler için tabloyu siz oluşturun.
  • Büyük import'ları BEGIN/COMMIT ile sarmalayın; aksi halde her satır ayrı bir transaction olur.
  • Dosyadaki kolon sırası tablodaki kolon sırasıyla birebir aynı olmalı.

Sırada: Veriyi Geri Dışa Aktarma

İçe aktarma işin yarısı. Aynı shell sorgu sonuçlarını veya tüm tabloları CSV, JSON ya da SQL olarak geri dökebiliyor — yedekleme, veri pipeline'ları ve veriyi başka araçlara devretmek için birebir. Bunu veri dışa aktarma bölümünde göreceğiz.

Sıkça Sorulan Sorular

SQLite'a bir CSV dosyasını nasıl aktarırım?

Veritabanını sqlite3 CLI ile açın, .mode csv komutuyla CSV moduna geçin ve ardından .import data.csv tablo_adi komutunu çalıştırın. Tablo henüz yoksa, SQLite dosyanın ilk satırını sütun adı olarak kullanıp tabloyu sizin için oluşturur. Tablo zaten varsa, dosyadaki her satır veri olarak eklenir — yani başlık satırını atlamak için genellikle .import --skip 1 kullanmanız gerekir.

Başlık satırı içeren bir CSV'yi mevcut bir SQLite tablosuna nasıl aktarırım?

.import --csv --skip 1 data.csv tablo_adi komutunu kullanın. --skip 1 parametresi SQLite'a ilk satırı yok saymasını söyler, böylece başlık satırı veri olarak eklenmez. Bu parametre olmadan, tablonuzda sütun adlarının kelime kelime yazıldığı bir satırla karşılaşırsınız.

SQLite CSV import işlemim neden 'expected N columns but found M' hatasıyla başarısız oluyor?

Dosyada tablonun beklediğinden farklı sayıda sütuna sahip satırlar var — genelde sebep satır içindeki kaçışsız virgüller, kapatılmamış tırnaklar veya dosya sonundaki boş bir satırdır. .mode tabs yerine .mode csv (ya da --csv) kullanın ki SQLite tırnak işaretlerini RFC 4180'e göre yorumlasın; ayrıca dosyayı bir editörle açıp kaçak ayraçları kontrol edin. CLI sorunlu satırın numarasını yazdırır, bu da hatalı kaydı bulmanın en hızlı yoludur.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA