COPY(7) | SQL - Dil Deyimleri | COPY(7) |
COPY - bir tablo ile bir dosya arasında veri kopyalar
COPY tablo_ismi [ ( sütun [, ...] ) ] FROM { 'dosya_ismi' | STDIN } [ [ WITH ] [ BINARY ] [ OIDS ] [ DELIMITER [ AS ] 'ayraç' ] [ NULL [ AS ] 'boş_dizge' ] [ CSV [ QUOTE [ AS ] 'tırnak' ] [ ESCAPE [ AS ] 'öncelem' ] [ FORCE NOT NULL sütun [, ...] ] COPY tablo_ismi [ ( sütun [, ...] ) ] TO { 'dosya_ismi' | STDOUT } [ [ WITH ] [ BINARY ] [ OIDS ] [ DELIMITER [ AS ] 'ayraç' ] [ NULL [ AS ] 'boş_dizge' ] [ CSV [ QUOTE [ AS ] 'tırnak' ] [ ESCAPE [ AS ] 'öncelem' ] [ FORCE QUOTE sütun [, ...] ]
COPY PostgreSQL tabloları ile standart dosya sistemi dosyaları arasında veri taşımak için kullanılır. COPY TO bir tablonun içeriğini bir dosyaya, COPY FROM ise bir dosyadaki veriyi bir tabloya kopyalar (mevcut bir tabloya veri eklemek şeklinde).
Eğer bir sütun listesi verilmişse, sadece belirtilen sütunların verileri kopyalamaya konu olur. Eğer sütun listesindeki sütunlar, tablodaki sütunların hepsini içermiyorsa, COPY FROM veri sağlanmamış sütunlara öntanımlı değerlerini yazar.
Bir dosya ismi ile kullanılan COPY, PostgreSQL sunucusunun okumak ve yazmak için doğrudan bir dosyaya erişmesini sağlar. Dosya sunucu tarafından erişilebilir olmalı ve dosya ismi sunucuya göre belirtilmelidir. STDIN veya STDOUT belirtildiğinde, veri istemci ile sunucu arasındaki bağlantı üzerinden iletilir.
COPY sadece normal tablolarla kullanılabilir, sanal tablolarla kullanılamaz.
BINARY seçeneği, tüm verinin metin değil ikilik biçimde saklanmasına/okunmasına sebep olur. Kısmen daha hızlı olsa da, ikilik biçimli dosyalar makine mimarileri ve farklı PostgreSQL sürümleri arasında daha az taşınabilirdir.
COPY TO tarafından okunan tablolarda SELECT, COPY FROM ile veri girilen tablolarda ise INSERT yetkiniz olmalıdır.
Bir COPY cümlesindeki isimli dosyalar istemci tarafından değil, sunucu tarafından okunur/yazılır. Bu nedenle, ya sunucu tarafında olmalı ya da sunucu makinedeki veritabanına erişiminiz olmalıdır. Bunlar PostgreSQL kullanıcısı (sunucuyu çalıştıran kullanıcı) tarafından okuma/yazma anlamında erişebilir olmalıdır, istemcinin değil. Bir dosyaya COPY isminin verilebilmesi, sunucunun erişebildiği her dosyaya okuma ve yazma yetkisi olduğundan, sadece veritabanı ayrıcalıklı kullanıcı için mümkündür.
COPY sözcüğünü psql'in \copy komutuyla karıştırmayın. \copy komutu psql istemcisinin erişebildiği bir dosyanın verisini almak/saklamak için COPY FROM STDIN veya COPY TO STDOUT çağrısı yapar. Bu nedenle, \copy kullanıldığında dosyaya erişilebilirlik ve erişim izinleri bakımından sunucu değil istemci etkindir.
COPY ile kullanılacak dosyanın daima mutlak dosya yolu ile belirtilmesi önerilir. Bu, COPY TO durumunda zorunludur, ama COPY FROM için bir dosyayı göreli dosya yolu ile belirtebilirsiniz; göreli dosya yolu, istemcinin çalışma dizinine göre değil, sunucu sürecinin çalışma dizinine (veri dizininin altında bir yer) göre yorumlanacaktır.
COPY FROM hedef tablodaki tetikleri ve sınama kısıtlarını da çağıracaktır. Ancak, kurallar çağrılmayacaktır.
COPY girdi ve çıktısı DateStyle değerinden etkilenecektir. Öntanımlı olmayan DateStyle değerleri kullanabilen diğer PostgreSQL kurulumlarına taşınabilirlik bakımından, COPY TO kullanmadan önce DateStyle değeri olarak ISO belirtmelisiniz.
COPY, işlemi ilk hatada durdurur. Bunun COPY TO için sorunlara yol açmaması gerekir, ama hedef tablo hatadan önceki satırları almış olacaktır. Bu satırlar görünür ve erişilebilir olmayacak ama yine de diskte yer kaplıyor olacaktır. Eğer hata çok büyük bir kopyalama işleminde gerçekleşmişse, bu, diskin önemli bir bölümünün yararsız kullanımına yol açacaktır. Yararsız kısımlardan kurtulmak için VACUUM kullanmayı deneyebilirsiniz.
COPY cümlesi BINARY veya CSV seçenekleri olmaksızın kullanılırken, verinin okunması veya yazılmasında, bir metin dosyasının her satırına bir tablonun bir satırı karşılık getirilir. Bir satırdaki sütunlar ayraç karakteri ile ayrılırlar. Sütunların değerleri ya çıktı işlevleri tarafından üretilmiş ya da girdi işlevleri tarafından özniteliklerinin veri türünde oldukları kabul edilen dizgelerdir. Belirtilen boş dizgeler sütunlara NULL değerler olarak yerleştirilir. Eğer girdi dosyasının bir satırı umulandan daha az ya da daha fazla sütun içeriyorsa, COPY FROM bir hata oluşturacaktır. Eğer OIDS belirtilmişse, nesne kimliği, veri sütunlarından önce, ilk sütun olarak okunur ya da yazılır.
Verinin sonu sadece bir tersbölü ve nokta (\.) içeren tek bir satırla ifade edilebilir. Veri dosyadan okunurken veri sonunun imlenmesi, dosya sonu zaten iyi algılanabildiğinden gerekli değildir; sadece 3.0 öncesi istemci protokolünü kullanan istemci uygulamaları ile veri kopyalanırken gerekli olur.
Sütun verisi içinde ayraç ve tırnak karakterleri kullanılırken, bunların ayraç ve tırnak karakterleri olarak algılanmaması için tersbölü karakteri (\) bunları öncelemekte kullanılabilir. Bir sütun değerinin içinde yer aldığında bir tersbölü ile öncelenmesi gereken karakterler şunlardır: tersbölü karakterinin kendisi, satırsonu, satırbaşı karakterleri ile ayraç ve tırnak olarak kullanılan karakterler.
Belirtilmiş bir boş dizge COPY TO tarafından tersbölü eklenmeden gönderilir; bunun aksine, COPY FROM girdi olan boş dizgeyi tersbölüleri silmeden önce eşleştirir. Bu nedenle, \N gibi bir boş dizge aslında bir veri değeri olan \N ile karışmaz (\\N olarak ifade edildiğinden).
COPY FROM tarafından tanınan tersbölü öncelemeli dizgeler:
Dizge Anlamı -------- --------------------------------------- \b Terbölü (ASCII 8) \f Sayfa ileri (ASCII 12) \n Satırsonu (ASCII 10) \r Satırbaşı (ASCII 13) \t Sekme (ASCII 9) \v Düşey sekme (ASCII 11) \rakamlar tersbölüden sonra gelen sekizlik tabandaki üç rakam bir karakterin sayısal değerini belirtir
Şu an, COPY TO tersbölü karakterini izleyen sekizlik rakamlar çıktılamayacak, ama yukarıda listelenmiş diğer dizgeleri kullanacaktır.
Yukarıdaki listede belirtilmemiş ama terbölü öncelemeli olarak belirtilmiş başka karakterler de olabilir, bu karakterler kendileri olarak değerlendirilecektir. Yine de tersbölülerin gereksiz yere kullanılmasından kaçınılmalıdır, çünkü istemeden veri sonunu imleyen \. ile boş dizgeyi imleyen \N dizgeleri üretilebilir. Bu dizgeler, bir tersbölü işlemi yapılmadan önce algılanmaya çalışılacaktır.
COPY için veri üreten uygulamaların veri içindeki satırsonu ve satırbaşı karakterlerini mutlaka \n ve \r dizgelerine dönüştürerek döndürmeleri önerilir. Şimdilik bu karakterler bu dizgelerle gösterilebiliyor olsa da ileride bu gösterimler kabul edilmeyebilir. Ayrıca bu karakterler, bilhassa dosyanın farklı makineler arasında aktarılması sırasında (örneğin, Unix ile Windows) bozulmalara yol açabilir.
COPY TO her satırı Unix tarzı satırsonu ("\n") ile sonlandıracaktır. Microsoft Windows üzerinde çalışan sunucular ise bunun yerine satırbaşı/satırsonu ("\r\n") çıktılayacaktır, fakat sadece bir sunucu dosyasına kopyalama için; platformlar arasında tutarlılığı sağlamak için COPY TO STDOUT sunucu platformundan bağımsız olarak daima "\n" gönderecektir. COPY FROM satırsonları ister satırbaşı, ister satırsonu, ister satırbaşı/satırsonu ile bitsin, satırları düzgün olarak elde edebilir. Veri içinde tersbölü ile öncelenmemiş satırsonu ve satırbaşı karakterlerinden dolayı hata oluşması riskini en aza indirmek için COPY FROM satırsonlarının beklendiği gibi bitmediğinden şikayet edecektir.
Bu biçim, hesap çizelgesi uygulamaları gibi başka uygulamalarla veri alışverişi yapmak için kullanılır. Bu kipte, PostgreSQL'in standart metin kipi tarafından kullanılan önceleme mekanizması yerine, bilinen CSV önceleme mekanizması kullanılır.
Her kayıttaki değerler DELIMITER karakteri ile ayrılır. Eğer değer ayraç karakteri, QUOTE karakteri, NULL dizge, bir satırsonu ya da satırbaşı karakteri içeriyorsa, değerin tamamı QUOTE karakterleri ile sarmalanır ve değerin içindeki QUOTE veya ESCAPE karakteri önceleme karakteri ile öncelenir. Ayrıca, belli sütunlarda NULL olmayan değerleri çıktılarken mutlaka tırnak kullanılacağını belirtmek için FORCE QUOTE kullanabilirsiniz.
CSV biçiminde, bir NULL değeri bir boş dizgeden ayırmanın standart bir yolu yoktur. PostgreSQL'in COPY oluşumu bunu tırnaklarla elde eder. Bir NULL, NULL dizge olarak çıktılanır ve tırnak içine alınmazken, NULL dizge ile eşleşen bir veri değeri tırnak içine alınır. Bu nedenle, öntanımlı ayarları kullanarak, bir NULL dizge tırnak içine alınmamış bir boş dizge olarak yazılırken, bir boş dizge tırnakların içine alınarak ("") yazılır. Değerlerin okunması da benzer şekilde yapıllır. Belli sütunlar için NULL dizge karşılaştırmasını önlemek için FORCE NOT NULL kullanabilirsiniz.
Çoğu uygulama standarddan çok bir uzlaşımın sonucu gibi görünen dosya biçimli, tuhaf CSV dosyalar üretir. Bu bakımdan, bu mekanizmanın bazı dosyaları kabul etmediğini ya da COPY oluşumunun ürettiği dosyaların başka uygulamalar tarafından işlenemediğini keşfedebilirsiniz.
COPY BINARY için kullanılan dosya biçimi PostgreSQL 7.4'de değişmiştir. Yeni dosya biçimi, bir dosya başlığı, sıfır ya da daha fazla sayıda satır verisi içeren demet ve bir dosya kuyruğu içerir. Başlık ve veri şimdi ağ bayt sıralamasındadır.
Dosya başlığı
Başlığın ek veri alanının kendinden menkul parçalardan oluşacağı düşünülmüştür. Bayrakları içeren alan ise okuyucuya ek veri alanında nelerin bulunduğunu açıklamak için tasarlanmamıştır. Başlığın ek veri alanının neleri içereceği daha sonraki dağıtımlara bırakılmıştır.
Bu tasarım, hem geriye uyumlu başlık eklemelerine (başlık ek veri parçaları veya düşük baytlardaki ek seçenek bitleri) hem de geriye uyumlu olmayan değişikliklere (yüksek baytlardaki seçenek bitleri bu değişiklikleri belirtmek için kullanılabileceği gibi gerekirse destek verisi ek veri alanına eklenebilir) izin verir.
Demetler
Alanlar arasında adımlama anlamında herhangi bir ek alan bulunmaz.
Şimdilik, bir COPY BINARY dosyasındaki tüm veri değerlerinin ikilik biçimde olacağı kabul edilmektedir. Gelecekte, sütun biçim kodlarının belirtileceği bir başlık alanının eklenebileceği umulmaktadır.
Demet verisinin ikilik biçimini daha iyi anlayabilmek için PostgreSQL'in kaynak dosyalarına bakınız. Her sütunun veri türü *send ve *recv işlevlerinde görülebilir. Bu işlevler genellike kaynak paketinin src/backend/utils/adt/ dizininde bulunur.
Nesne kimlikleri dosyada bulunuyorsa, OID alanı alan sayısını belirten tamsayıdan hemen sonra gelir ve alan sayısına dahil edilmemesi dışında normal bir alandır. Yani, normal alanlar gibi uzunluğunu belirten bir tamsayı ile başlar. Böylece 4 baytlık ve 8 baytlık nesne kimliklerinin belirtilebilmesi mümkün olur, hatta istenirse, nesne kimliklerinin boş olarak gösterilmesini de mümkün kılar.
Dosya Kuyruğu
Eğer alan sayısını belirten tamsayı ne -1 ne de umulan sütun sayısını içeriyorsa, okuyucunun bir hata raporlaması gerekir. Bu, verinin düzgün olarak alınıp alınmadığıyla ilgili ek bir sınama da sağlar.
Alan ayracı olarak | kullanarak istemciye bir tablonun kopyalanması:
COPY country TO STDOUT WITH DELIMITER '|';
Verinin bir dosyadan country tablosuna kopyalanması:
COPY country FROM '/usr1/proj/bray/sql/country_data';
STDIN'den bir tabloya kopyalanmaya uygun veri örneği:
AF AFGHANISTAN AL ALBANIA DZ ALGERIA ZM ZAMBIA ZW ZIMBABWE
Burada her satırın içindeki boşluklar aslında birer sekme karakteridir.
Aşağıda aynı veri ikilik biçimde çıktılanmıştır. Buradaki veri bir Unix aracı olan od -c ile süzüldükten sonra gösterilmiştir. Tablo üç alana sahiptir; ilk alan char(2) türünde, ikinci alan text türünde, üçüncü alan ise integer türündedir. Tüm satırların üçüncü sütunları birer NULL değer içermektedir.
0000000 P G C O P Y \n 377 \r \n \0 \0 \0 \0 \0 \0 0000020 \0 \0 \0 \0 003 \0 \0 \0 002 A F \0 \0 \0 013 A 0000040 F G H A N I S T A N 377 377 377 377 \0 003 0000060 \0 \0 \0 002 A L \0 \0 \0 007 A L B A N I 0000100 A 377 377 377 377 \0 003 \0 \0 \0 002 D Z \0 \0 \0 0000120 007 A L G E R I A 377 377 377 377 \0 003 \0 \0 0000140 \0 002 Z M \0 \0 \0 006 Z A M B I A 377 377 0000160 377 377 \0 003 \0 \0 \0 002 Z W \0 \0 \0 \b Z I 0000200 M B A B W E 377 377 377 377 377 377
SQL standardında COPY diye bir deyim yoktur.
Aşağıdaki sözdizimi PostgreSQL'in 7.3 sürümünden önce kullanılmaktaydı ve hala desteklenmektedir:
COPY [ BINARY ] tablo_ismi [ WITH OIDS ] FROM { 'dosya_ismi' | STDIN } [ [USING] DELIMITERS 'ayraç' ] [ WITH NULL AS 'boş_dizge' ] COPY [ BINARY ] tablo_ismi [ WITH OIDS ] TO { 'dosya_ismi' | STDOUT } [ [USING] DELIMITERS 'ayraç' ] [ WITH NULL AS 'boş_dizge' ]
Nilgün Belma Bugüner <nilgun (at) belgeler·gen·tr>, Nisan 2005
PostgreSQL |