Yanıtlar:
Ortaya çıkan dosyayı sunucuda mı yoksa istemcide mi istiyorsunuz?
Yeniden kullanımı veya otomatikleştirilmesi kolay bir şey istiyorsanız, Postgresql'in yerleşik COPY komutunu kullanabilirsiniz. Örneğin
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Bu yaklaşım tamamen uzak sunucuda çalışır - yerel bilgisayarınıza yazamaz. Ayrıca Postgres "süper kullanıcı" (normalde "root" olarak adlandırılır) olarak çalıştırılması gerekir, çünkü Postgres bu makinenin yerel dosya sistemiyle kötü şeyler yapmasını durduramaz.
Bu aslında bir süper kullanıcı olarak bağlanmak zorunda olduğunuz anlamına gelmez (farklı bir güvenlik riski olabilecek otomatikleştirme), çünkü bir süper kullanıcıymış gibi çalışan bir işlev yapmak için SECURITY DEFINER
seçeneğiCREATE FUNCTION
kullanabilirsiniz .
Önemli olan, fonksiyonunuzun sadece güvenliği atlamak için değil, ek kontroller yapmak için orada olmasıdır - böylece tam olarak ihtiyacınız olan verileri dışa aktaran bir fonksiyon yazabilir veya çeşitli seçenekleri kabul edebilecekleri bir şey yazabilirsiniz katı bir beyaz liste ile tanışın. İki şeyi kontrol etmeniz gerekir:
GRANT
veritabanındaki s tarafından tanımlanır , ancak işlev şimdi bir süper kullanıcı olarak çalışmaktadır, bu nedenle normalde "sınırların dışında" olacak tablolara tam olarak erişilebilir olacaktır. Muhtemelen birisinin işlevinizi çağırmasına ve "kullanıcılar" tablonuzun sonuna satır eklemesine izin vermek istemezsiniz ...Sıkı koşulları karşılayan dosyaları ve tabloları dışa aktarma (veya içe aktarma) işlevlerinin bazı örnekleri de dahil olmak üzere , bu yaklaşımı genişleten bir blog yazısı yazdım .
Diğer yaklaşım, istemci tarafında , yani uygulamanızda veya komut dosyanızda dosya işlemeyi yapmaktır . Postgres sunucusunun hangi dosyayı kopyaladığınızı bilmesine gerek yoktur, sadece verileri tükürür ve istemci dosyayı bir yere koyar.
Bunun altında yatan sözdizimi COPY TO STDOUT
komuttur ve pgAdmin gibi grafik araçları sizin için güzel bir iletişim kutusunda sarar.
psql
Komut satırı istemcisi adı verilen özel bir "meta-komutu" vardır \copy
"gerçek" aynı seçenekleri alır COPY
, ancak istemci içinde çalıştırılır:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
;
SQL komutlarının aksine meta komutlar yeni satırla sonlandığından , sonlandırma olmadığını unutmayın .
Gönderen docs :
COPY'yi psql yönergesi \ copy ile karıştırmayın. \ copy STDIN'den COPY veya STDOUT'a COPY'yi çağırır ve ardından verileri psql istemcisinin erişebileceği bir dosyaya getirir / depolar. Bu nedenle, \ copy kullanıldığında dosya erişilebilirliği ve erişim hakları sunucuya değil istemciye bağlıdır.
Uygulama programlama dilinizin verileri itme veya alma desteği de olabilir , ancak giriş / çıkış akışını bağlamanın bir yolu olmadığından, COPY FROM STDIN
/ TO STDOUT
standart bir SQL deyimi içinde / kullanamazsınız . PHP'nin PostgreSQL işleyicisi ( PDO değil ) çok büyük pg_copy_from
ve pg_copy_to
bir PHP dizisine kopyalanan ve büyük veri kümeleri için verimli olmayabilecek işlevleri içerir .
\copy
çalışır - orada, yollar istemciye göredir ve noktalı virgül gerekmez. Düzenlememe bakın.
\copy
göre bir astar olmak gerekiyor. Böylece sql'i istediğiniz gibi biçimlendirmenin güzelliğini elde edemezsiniz ve sadece çevresine bir kopya / işlev koyabilirsiniz.
\copy
özel bir meta-komut içinde psql
komut satırı istemcisi . PgAdmin gibi diğer istemcilerde çalışmaz; muhtemelen bu işi yapmak için grafik sihirbazları gibi kendi araçlarına sahip olacaklar.
Birkaç çözüm var:
psql
komutpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
Bu, SSH aracılığıyla kullanabileceğiniz büyük bir avantaja sahiptir, örneğin ssh postgres@host command
-
copy
komutuCOPY (SELECT * from users) To '/tmp/output.csv' With CSV;
>psql dbname
psql>\f ','
psql>\a
psql>\o '/tmp/output.csv'
psql>SELECT * from users;
psql>\q
Hepsi komut dosyalarında kullanılabilir, ancak # 1'i tercih ederim.
Terminalde (db'ye bağlıyken) cvs dosyasına çıkış ayarlayın
1) Alan ayırıcıyı şu şekilde ayarlayın ','
:
\f ','
2) Çıktı formatını hizasız olarak ayarlayın:
\a
3) sadece tuples göster:
\t
4) Set çıkışı:
\o '/tmp/yourOutputFile.csv'
5) Sorgunuzu yürütün:
:select * from YOUR_TABLE
6) Çıktı:
\o
Daha sonra, bu konumda csv dosyanızı bulabileceksiniz:
cd /tmp
scp
Komut kullanarak kopyalayın veya nano kullanarak düzenleyin:
nano /tmp/yourOutputFile.csv
COPY
Ya da \copy
(standart CSV biçimine dönüştürmek) doğru kolu yaklaşımları; bunu yapar?
Başlıklar ile birlikte belirli bir tablonun tüm sütunlarıyla ilgileniyorsanız,
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
Bu biraz daha basit
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
ki bildiklerime göre eşdeğerdir.
Bu bilgi gerçekten iyi temsil edilmiyor. Bunu türetmek için ikinci kez ihtiyacım olduğu için, bunu kendime başka bir şey olmadığını hatırlatmak için buraya koyacağım.
Bunu yapmanın gerçekten en iyi yolu (CSV'yi postgres'ten almak) COPY ... TO STDOUT
komutu kullanmaktır . Yine de buradaki yanıtlarda gösterilen şekilde yapmak istemezsiniz. Komutu kullanmanın doğru yolu:
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
Ssh üzerinde kullanım için harika:
$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv
Ssh üzerinde docker içinde kullanmak için harika:
$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Yerel makinede bile harika:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Yoksa yerel makinedeki liman işçisinin içinde mi?
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
Veya bir kubernetes kümesinde, docker'da, HTTPS üzerinde ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
Çok yönlü, çok virgül!
Evet yaptım, işte notlarım:
Kullanılması /copy
etkili bir türlü sistem dosya işlemleri yürütür psql
o çalıştırdığı kullanıcı olarak, komut çalışıyorsa 1 . Uzak bir sunucuya bağlanırsanız, uzak sunucuya psql
/ sunucudan yürütülen sistemdeki veri dosyalarını kopyalamak kolaydır .
COPY
sunucuda, arka uç işlem kullanıcı hesabı (varsayılan postgres
) olarak dosya işlemlerini yürütür , dosya yolları ve izinler denetlenir ve buna göre uygulanır. Kullanılıyorsa, TO STDOUT
dosya izinleri denetimleri atlanır.
Bu seçeneklerin her ikisi de psql
, sonuçta elde edilen CSV'nin eninde sonunda olmasını istediğiniz yerde sistemde yürütülmüyorsa, sonraki dosya hareketini gerektirir . Deneyimlerime göre, çoğunlukla uzak sunucularla çalıştığınızda bu en olası durum.
Basit CSV çıkışı için ssh üzerinden TCP / IP tüneli gibi bir şeyi uzak bir sisteme yapılandırmak daha karmaşıktır, ancak diğer çıkış biçimleri (ikili) için /copy
yerel bir yürütme tünel bağlantısı üzerinden daha iyi olabilir psql
. Benzer bir şekilde, büyük ithalatlar için, kaynak dosyayı sunucuya taşımak ve kullanmak COPY
muhtemelen en yüksek performans seçeneğidir.
Psql parametreleriyle çıktıyı CSV gibi biçimlendirebilirsiniz, ancak çağrı cihazını devre dışı bırakmayı ve üstbilgileri almayı hatırlamak zorunda kalmak gibi dezavantajlar vardır:
$ psql -P pager=off -d mydb -t -A -F',' -c 'select * from groups;'
2,Technician,Test 2,,,t,,0,,
3,Truck,1,2017-10-02,,t,,0,,
4,Truck,2,2017-10-02,,t,,0,,
Hayır, bir araç derlemeden ve / veya kurmadan CSV'yi sunucumdan çıkarmak istiyorum.
psql
bunu sizin için yapabilir:
edd@ron:~$ psql -d beancounter -t -A -F"," \
-c "select date, symbol, day_close " \
"from stockprices where symbol like 'I%' " \
"and date >= '2009-10-02'"
2009-10-02,IBM,119.02
2009-10-02,IEF,92.77
2009-10-02,IEV,37.05
2009-10-02,IJH,66.18
2009-10-02,IJR,50.33
2009-10-02,ILF,42.24
2009-10-02,INTC,18.97
2009-10-02,IP,21.39
edd@ron:~$
man psql
Burada kullanılan seçeneklerle ilgili yardım için bkz .
Yeni sürüm - psql 12 - destekleyecektir --csv
.
--csv
CSV (Virgülle Ayrılmış Değerler) çıkış moduna geçer. Bu \ pset format csv'ye eşdeğerdir .
csv_fieldsep
CSV çıktı biçiminde kullanılacak alan ayırıcısını belirtir. Ayırıcı karakter bir alanın değerinde görünürse, bu alan standart CSV kurallarına göre çift tırnak içinde verilir. Varsayılan, virgüldür.
Kullanımı:
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv -P csv_fieldsep='^' postgres
psql -c "SELECT * FROM pg_catalog.pg_tables" --csv postgres > output.csv
PgAdmin III'te, sorgu penceresinden dosyaya dışa aktarma seçeneği vardır. Ana menüde Sorgu -> Dosyaya yürüt veya aynı şeyi yapan bir düğme var (sadece sorguyu çalıştıran düz yeşil üçgenin aksine mavi disketli yeşil bir üçgen). Sorguyu sorgu penceresinden çalıştırmıyorsanız, IMSoP'nin önerdiğini yaparım ve copy komutunu kullanırdım.
Deseni psql2csv
kapsüle eden COPY query TO STDOUT
ve uygun CSV ile sonuçlanan küçük bir araç yazdım . Arayüzü benzer psql
.
psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY
Sorgunun, varsa STDIN içeriği veya son bağımsız değişken olduğu varsayılır. Aşağıdakiler haricinde diğer tüm argümanlar psql'ye iletilir:
-h, --help show help, then exit
--encoding=ENCODING use a different encoding than UTF8 (Excel likes LATIN1)
--no-header do not output a header
Daha uzun sorgunuz varsa ve psql kullanmak istiyorsanız, sorgunuzu bir dosyaya yerleştirin ve aşağıdaki komutu kullanın:
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
-F","
yerine kullanmak zorunda kaldım-F";"
DataGrip , JetBrains tarafından bir veritabanı IDE tavsiye . Sen edebilir bir CSV dosyasına bir SQL sorgusu ihracat ve kolaylıkla SSH tünel ayarlayabilirsiniz. Belgeler "sonuç kümesi" ne atıfta bulunursa, konsoldaki bir SQL sorgusu tarafından döndürülen sonucu ifade eder.
DataGrip ile ilişkili değilim, sadece ürünü seviyorum!
Web tarayıcınızda bir veritabanı istemcisi olan JackDB bunu gerçekten kolaylaştırıyor. Özellikle Heroku'daysan.
Uzak veritabanlarına bağlanmanıza ve üzerlerinde SQL sorguları çalıştırmanıza olanak tanır.
Kaynak
(kaynak: jackdb.com )
DB'niz bağlandıktan sonra bir sorgu çalıştırabilir ve CSV veya TXT'ye dışa aktarabilirsiniz (sağ alt kısma bakın).
Not: Hiçbir şekilde JackDB'ye bağlı değilim. Şu anda ücretsiz hizmetlerini kullanıyorum ve harika bir ürün olduğunu düşünüyorum.
@ Skeller88'in isteği üzerine, her yanıtı okumayan insanlar tarafından kaybolmaması için yorumumu bir cevap olarak yeniden gönderiyorum ...
DataGrip ile ilgili sorun, cüzdanınızı kavramasıdır. Ücretsiz değil. DBeaver'ın topluluk sürümünü dbeaver.io adresinde deneyin. Tüm popüler veritabanlarını destekleyen SQL programcıları, DBA'lar ve analistler için bir FOSS çok platformlu veritabanı aracıdır: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto, vb.
DBeaver Community Edition, bir veritabanına bağlanmayı, verileri almak için sorgular yayınlamayı ve ardından CSV, JSON, SQL veya diğer yaygın veri biçimlerine kaydetmek için sonuç kümesini indirmeyi önemsiz kılar. Postgres için TOAD, SQL Server için TOAD veya Oracle için Toad için uygun bir FOSS rakibi.
DBeaver ile hiçbir bağlantım yok. Fiyat ve işlevselliği seviyorum, ancak keşke kullanıcıların DBeaver / Eclipse uygulamasını daha fazla açmasını ve kullanıcıların doğrudan grafik ve grafikler oluşturmak için yıllık abonelik için ödeme yapmasını istemek yerine DBeaver / Eclipse'a analitik widget'ları eklemesini kolaylaştırdı. uygulama. Java kodlama becerilerim paslı ve Eclipse widget'larının nasıl oluşturulacağını öğrenmek için haftalar sürmekten hoşlanmıyorum, sadece DBeaver'ın DBeaver Topluluk Sürümü'ne üçüncü taraf widget'ları ekleme yeteneğini devre dışı bıraktığını bulmak için.
DBeaver kullanıcıları, DBeaver'ın Topluluk Sürümü'ne eklemek üzere analitik widget'ları oluşturma adımları hakkında bilgi sahibi mi?
import json
cursor = conn.cursor()
qry = """ SELECT details FROM test_csvfile """
cursor.execute(qry)
rows = cursor.fetchall()
value = json.dumps(rows)
with open("/home/asha/Desktop/Income_output.json","w+") as f:
f.write(value)
print 'Saved to File Successfully'