วิธีที่ง่ายที่สุดในการบันทึกเอาต์พุต PL / pgSQL จากฐานข้อมูล PostgreSQL เป็นไฟล์ CSV คืออะไร?
ฉันใช้ PostgreSQL 8.4 กับ pgAdmin III และปลั๊กอิน PSQL ที่ฉันเรียกใช้แบบสอบถาม
วิธีที่ง่ายที่สุดในการบันทึกเอาต์พุต PL / pgSQL จากฐานข้อมูล PostgreSQL เป็นไฟล์ CSV คืออะไร?
ฉันใช้ PostgreSQL 8.4 กับ pgAdmin III และปลั๊กอิน PSQL ที่ฉันเรียกใช้แบบสอบถาม
คำตอบ:
คุณต้องการไฟล์ผลลัพธ์บนเซิร์ฟเวอร์หรือบนไคลเอนต์หรือไม่?
หากคุณต้องการบางสิ่งที่ง่ายต่อการใช้ซ้ำหรือทำให้เป็นอัตโนมัติคุณสามารถใช้คำสั่งCOPY ที่สร้างขึ้นใน Postgresql เช่น
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
วิธีการนี้ทำงานบนเซิร์ฟเวอร์ระยะไกลทั้งหมด - ไม่สามารถเขียนลงในเครื่องคอมพิวเตอร์ของคุณได้ นอกจากนี้ยังต้องมีการเรียกใช้เป็น "superuser" ของ Postgres (ปกติเรียกว่า "root") เนื่องจาก Postgres ไม่สามารถหยุดสิ่งที่น่ารังเกียจด้วยระบบไฟล์ภายในเครื่องของเครื่องนั้นได้
แต่นั่นไม่ได้หมายความว่าคุณจริงจะต้องมีการเชื่อมต่อเป็น superuser (อัตโนมัติที่จะเสี่ยงต่อความปลอดภัยของชนิดที่แตกต่างกัน) เพราะคุณสามารถใช้ตัวเลือกในการที่จะทำให้ฟังก์ชั่นที่ทำงานราวกับว่าคุณเป็น superuserSECURITY DEFINER
CREATE FUNCTION
ส่วนที่สำคัญคือฟังก์ชั่นของคุณจะมีการตรวจสอบเพิ่มเติมไม่ใช่แค่ผ่านการรักษาความปลอดภัยดังนั้นคุณสามารถเขียนฟังก์ชั่นที่ส่งออกข้อมูลตรงตามที่คุณต้องการหรือคุณสามารถเขียนบางสิ่งที่สามารถยอมรับตัวเลือกต่าง ๆ ได้ พบบัญชีขาวที่เข้มงวด คุณต้องตรวจสอบสองสิ่ง:
GRANT
s ในฐานข้อมูล แต่ตอนนี้ฟังก์ชั่นกำลังทำงานเป็น superuser ดังนั้นตารางที่ปกติจะ "เกินขอบเขต" จะสามารถเข้าถึงได้อย่างเต็มที่ คุณอาจไม่ต้องการให้ใครบางคนเรียกใช้ฟังก์ชันของคุณและเพิ่มแถวที่ส่วนท้ายของตาราง "ผู้ใช้" ของคุณ ...ฉันได้เขียนโพสต์บล็อกที่ขยายในวิธีนี้รวมถึงตัวอย่างของฟังก์ชั่นที่ส่งออก (หรือนำเข้า) ไฟล์และตารางตามเงื่อนไขที่เข้มงวด
อีกวิธีคือทำการจัดการไฟล์ในฝั่งไคลเอ็นต์เช่นในแอปพลิเคชันหรือสคริปต์ของคุณ เซิร์ฟเวอร์ Postgres ไม่จำเป็นต้องรู้ว่าไฟล์ใดที่คุณกำลังคัดลอกมันแค่กระจายข้อมูลและไคลเอนต์วางไว้ที่อื่น
ไวยากรณ์พื้นฐานสำหรับสิ่งนี้คือCOPY TO STDOUT
คำสั่งและเครื่องมือกราฟิกเช่น pgAdmin จะล้อมรอบคุณไว้ในกล่องโต้ตอบที่ดี
psql
ลูกค้าบรรทัดคำสั่งที่มีความพิเศษ "เมตา" คำสั่งที่เรียกว่า\copy
ซึ่งจะมีตัวเลือกทั้งหมดเช่นเดียวกับ "ของจริง" COPY
แต่จะดำเนินการภายในไคลเอนต์:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
โปรดทราบว่าไม่มีการยกเลิก;
เนื่องจากคำสั่ง meta ถูกยกเลิกโดยบรรทัดใหม่ซึ่งแตกต่างจากคำสั่ง SQL
จากเอกสาร :
อย่าสับสน COPY กับคำสั่ง psql \ copy \ copy เรียกใช้คัดลอกจาก STDIN หรือคัดลอกไปยัง STDOUT แล้วดึง / จัดเก็บข้อมูลในไฟล์ที่เข้าถึงได้โดยไคลเอนต์ psql ดังนั้นความสามารถในการเข้าถึงไฟล์และสิทธิ์การเข้าถึงจึงขึ้นอยู่กับไคลเอ็นต์มากกว่าเซิร์ฟเวอร์เมื่อใช้ \ copy
ภาษาโปรแกรมแอปพลิเคชันของคุณอาจรองรับการดึงหรือดึงข้อมูล แต่โดยทั่วไปคุณไม่สามารถใช้COPY FROM STDIN
/ TO STDOUT
ภายในคำสั่ง SQL มาตรฐานได้เนื่องจากไม่มีวิธีการเชื่อมต่ออินพุต / เอาต์พุตสตรีม ตัวจัดการ PostgreSQL ของ PHP ( ไม่ใช่ PDO) รวมถึงพื้นฐานpg_copy_from
และpg_copy_to
ฟังก์ชันที่คัดลอกไปยัง / จากอาร์เรย์ PHP ซึ่งอาจไม่มีประสิทธิภาพสำหรับชุดข้อมูลขนาดใหญ่
\copy
ทำงานเหมือนกัน - นั่นคือพา ธ นั้นสัมพันธ์กับลูกค้าและไม่จำเป็น / อนุญาตใช้เครื่องหมายอัฒภาค ดูการแก้ไขของฉัน
\copy
จะต้องเป็นหนึ่งซับ ดังนั้นคุณจะไม่ได้รับความสวยงามในการจัดรูปแบบ sql ตามที่คุณต้องการและเพียงแค่ใส่สำเนา / ฟังก์ชันรอบ ๆ
\copy
เป็นพิเศษ meta-คำสั่งในpsql
ลูกค้าบรรทัดคำสั่ง มันจะไม่ทำงานในลูกค้ารายอื่นเช่น pgAdmin; พวกเขาอาจจะมีเครื่องมือของตัวเองเช่นพ่อมดกราฟิกเพื่อทำงานนี้
มีหลายวิธี:
psql
คำสั่งpsql -d dbname -t -A -F"," -c "select * from users" > output.csv
นี่เป็นข้อได้เปรียบที่ยิ่งใหญ่ที่คุณสามารถใช้ได้ผ่าน SSH เช่นssh postgres@host command
- ช่วยให้คุณได้รับ
copy
คำสั่งpostgresCOPY (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
พวกเขาทั้งหมดสามารถใช้ในสคริปต์ แต่ฉันชอบ # 1
ในเทอร์มินัล (ในขณะที่เชื่อมต่อกับ db) ให้ตั้งค่าเอาต์พุตเป็นไฟล์ cvs
1) ตั้งค่าฟิลด์ seperator เป็น','
:
\f ','
2) กำหนดรูปแบบผลลัพธ์ที่ไม่ได้จัดแนว:
\a
3) แสดงสิ่งอันดับเท่านั้น:
\t
4) ตั้งค่าเอาต์พุต:
\o '/tmp/yourOutputFile.csv'
5) ดำเนินการค้นหาของคุณ:
:select * from YOUR_TABLE
6) เอาท์พุท:
\o
จากนั้นคุณจะสามารถค้นหาไฟล์ csv ของคุณในตำแหน่งนี้:
cd /tmp
คัดลอกโดยใช้scp
คำสั่งหรือแก้ไขโดยใช้นาโน:
nano /tmp/yourOutputFile.csv
COPY
หรือ\copy
วิธีการจัดการอย่างถูกต้อง (แปลงรูปแบบ CSV มาตรฐาน); ทำสิ่งนี้?
หากคุณสนใจในคอลัมน์ทั้งหมดของตารางโดยเฉพาะพร้อมกับส่วนหัวคุณสามารถใช้
COPY table TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
มันง่ายกว่านิดหน่อย
COPY (SELECT * FROM table) TO '/some_destdir/mycsv.csv' WITH CSV HEADER;
ซึ่งเท่าที่ความรู้ของฉันจะเท่ากัน
ข้อมูลนี้ไม่ได้เป็นตัวแทนที่ดีจริงๆ เนื่องจากนี่เป็นครั้งที่สองที่ฉันจำเป็นต้องได้รับสิ่งนี้ฉันจะวางสิ่งนี้ไว้ที่นี่เพื่อเตือนตัวเองหากไม่มีอะไรอื่น
จริงๆวิธีที่ดีที่สุดในการทำเช่นนี้ (รับ CSV จาก postgres) คือการใช้COPY ... TO STDOUT
คำสั่ง แม้ว่าคุณจะไม่ต้องการทำตามวิธีที่แสดงในคำตอบที่นี่ วิธีที่ถูกต้องในการใช้คำสั่งคือ:
COPY (select id, name from groups) TO STDOUT WITH CSV HEADER
มันยอดเยี่ยมสำหรับการใช้งานผ่าน ssh:
$ ssh psqlserver.example.com 'psql -d mydb "COPY (select id, name from groups) TO STDOUT WITH CSV HEADER"' > groups.csv
มันยอดเยี่ยมสำหรับการใช้งานภายใน docker over ssh:
$ ssh pgserver.example.com 'docker exec -tu postgres postgres psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
มันยอดเยี่ยมมากสำหรับเครื่องจักรท้องถิ่น:
$ psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
หรือนักเทียบท่าภายในเครื่องท้องถิ่น:
docker exec -tu postgres postgres psql -d mydb -c 'COPY groups TO STDOUT WITH CSV HEADER' > groups.csv
หรือบน kubernetes cluster, ใน docker, มากกว่า HTTPS ??:
kubectl exec -t postgres-2592991581-ws2td 'psql -d mydb -c "COPY groups TO STDOUT WITH CSV HEADER"' > groups.csv
เครื่องหมายจุลภาคที่หลากหลายมาก!
ใช่ฉันทำนี่คือบันทึกของฉัน:
ใช้/copy
อย่างมีประสิทธิภาพดำเนินการการดำเนินงานไฟล์ในระบบใดpsql
คำสั่งที่ทำงานอยู่ในขณะที่ผู้ใช้ที่รันมัน1 หากคุณเชื่อมต่อกับเซิร์ฟเวอร์ระยะไกลคุณสามารถคัดลอกไฟล์ข้อมูลในระบบที่เรียกใช้งานpsql
ไปยัง / จากเซิร์ฟเวอร์ระยะไกลได้ง่าย
COPY
เรียกใช้งานการดำเนินการไฟล์บนเซิร์ฟเวอร์เป็นบัญชีผู้ใช้กระบวนการแบ็กเอนด์ (ค่าเริ่มต้นpostgres
) เส้นทางไฟล์และการอนุญาตจะถูกตรวจสอบและนำไปใช้อย่างเหมาะสม ถ้าใช้TO STDOUT
แล้วการตรวจสอบการอนุญาตของไฟล์จะถูกข้ามไป
ตัวเลือกทั้งสองนี้ต้องการการเคลื่อนไหวของไฟล์ในภายหลัง psql
ไม่ได้ดำเนินการในระบบที่คุณต้องการให้ CSV ที่เป็นผลลัพธ์อยู่ในที่สุด นี่เป็นกรณีที่เป็นไปได้มากที่สุดในประสบการณ์ของฉันเมื่อคุณทำงานกับเซิร์ฟเวอร์ระยะไกลเป็นส่วนใหญ่
มันมีความซับซ้อนมากขึ้นในการกำหนดค่าบางอย่างเช่นอุโมงค์ TCP / IP บน ssh ไปยังระบบระยะไกลสำหรับเอาต์พุต CSV อย่างง่าย แต่สำหรับรูปแบบเอาต์พุตอื่น ๆ (ไบนารี) มันอาจจะดีกว่าที่จะ/copy
ผ่านการเชื่อมต่อที่ใช้ช่องpsql
สัญญาณ ในหลอดเลือดดำที่คล้ายกันสำหรับการนำเข้าขนาดใหญ่การย้ายไฟล์ต้นฉบับไปยังเซิร์ฟเวอร์และการใช้COPY
อาจเป็นตัวเลือกที่มีประสิทธิภาพสูงสุด
ด้วยพารามิเตอร์ psql คุณสามารถจัดรูปแบบผลลัพธ์เช่น CSV แต่มีข้อเสียเช่นต้องจำไว้ว่าให้ปิดใช้งานเพจเจอร์และไม่ได้รับส่วนหัว:
$ 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,,
ไม่ฉันต้องการนำ CSV ออกจากเซิร์ฟเวอร์ของฉันโดยไม่ต้องรวบรวมและ / หรือติดตั้งเครื่องมือ
ฉันต้องใช้ \ COPY เพราะฉันได้รับข้อความแสดงข้อผิดพลาด:
ERROR: could not open file "/filepath/places.csv" for writing: Permission denied
ดังนั้นฉันจึงใช้:
\Copy (Select address, zip From manjadata) To '/filepath/places.csv' With CSV;
และมันก็ใช้งานได้
psql
สามารถทำสิ่งนี้เพื่อคุณ:
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
ความช่วยเหลือเกี่ยวกับตัวเลือกที่ใช้ที่นี่
ฉันกำลังทำงานกับ AWS Redshift ซึ่งไม่รองรับCOPY TO
คุณสมบัตินี้
เครื่องมือ BI ของฉันรองรับ CSV ที่คั่นด้วยแท็บดังนั้นฉันจึงใช้สิ่งต่อไปนี้:
psql -h dblocation -p port -U user -d dbname -F $'\t' --no-align -c "SELECT * FROM TABLE" > outfile.csv
รุ่นใหม่ - psql 12 - --csv
จะให้การสนับสนุน
--csv
เปลี่ยนเป็นโหมดเอาต์พุต CSV (คั่นด้วยเครื่องหมายจุลภาค) นี้จะเทียบเท่ากับ\ รูปแบบ pset CSV
csv_fieldsep
ระบุตัวคั่นฟิลด์ที่จะใช้ในรูปแบบเอาต์พุต CSV หากอักขระตัวคั่นปรากฏในค่าของฟิลด์ฟิลด์นั้นจะถูกส่งออกภายในเครื่องหมายคำพูดคู่ตามกฎ CSV มาตรฐาน ค่าเริ่มต้นคือเครื่องหมายจุลภาค
การใช้งาน:
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 มีตัวเลือกในการส่งออกไปยังไฟล์จากหน้าต่างแบบสอบถาม ในเมนูหลักคือ Query -> Execute to file หรือมีปุ่มที่ทำสิ่งเดียวกัน (เป็นรูปสามเหลี่ยมสีเขียวที่มีแผ่นฟลอปปี้สีฟ้าเมื่อเทียบกับสามเหลี่ยมสีเขียวธรรมดาที่เพิ่งเรียกใช้แบบสอบถาม) หากคุณไม่ได้ใช้แบบสอบถามจากหน้าต่างแบบสอบถามแล้วฉันจะทำสิ่งที่แนะนำ IMSoP และใช้คำสั่งคัดลอก
ฉันลองหลายสิ่งหลายอย่าง แต่มีไม่กี่คนที่สามารถให้ CSV ที่ฉันต้องการพร้อมรายละเอียดส่วนหัว
นี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน
psql -d dbame -U username \
-c "COPY ( SELECT * FROM TABLE ) TO STDOUT WITH CSV HEADER " > \
OUTPUT_CSV_FILE.csv
ฉันได้เขียนเครื่องมือเล็กน้อยที่เรียกpsql2csv
ว่า encapsulate COPY query TO STDOUT
รูปแบบทำให้เกิด CSV ที่เหมาะสม psql
อินเตอร์เฟซของมันจะคล้ายกับ
psql2csv [OPTIONS] < QUERY
psql2csv [OPTIONS] QUERY
แบบสอบถามจะถือว่าเป็นเนื้อหาของ STDIN ถ้ามีหรืออาร์กิวเมนต์สุดท้าย อาร์กิวเมนต์อื่นทั้งหมดถูกส่งต่อไปยัง psql ยกเว้นสิ่งเหล่านี้:
-h, --help show help, then exit
--encoding=ENCODING use a different encoding than UTF8 (Excel likes LATIN1)
--no-header do not output a header
หากคุณมีเคียวรีนานขึ้นและคุณต้องการใช้ psql ให้ใส่เคียวรีของคุณไปยังไฟล์และใช้คำสั่งต่อไปนี้:
psql -d my_db_name -t -A -F";" -f input-file.sql -o output-file.csv
-F","
แทน-F";"
การสร้างไฟล์ CSV ที่จะเปิดอย่างถูกต้องใน MS Excel
ในการดาวน์โหลดไฟล์ CSV ที่มีชื่อคอลัมน์ในฐานะ HEADER ให้ใช้คำสั่งนี้:
Copy (Select * From tableName) To '/tmp/fileName.csv' With CSV HEADER;
ฉันขอแนะนำDataGrip , IDE ฐานข้อมูลโดย JetBrains คุณสามารถส่งออกแบบสอบถาม SQL ไปยังไฟล์ CSVและสามารถตั้งค่าช่องสัญญาณ ssh ได้อย่างง่ายดาย เมื่อเอกสารอ้างอิงถึง "ชุดผลลัพธ์" เอกสารเหล่านั้นหมายถึงผลลัพธ์ที่ส่งคืนโดยแบบสอบถาม SQL ในคอนโซล
ฉันไม่ได้เกี่ยวข้องกับ DataGrip ฉันรักผลิตภัณฑ์มาก!
JackDBลูกค้าฐานข้อมูลในเว็บเบราว์เซอร์ของคุณทำให้เป็นเรื่องง่ายมาก โดยเฉพาะอย่างยิ่งถ้าคุณอยู่ใน Heroku
มันช่วยให้คุณเชื่อมต่อกับฐานข้อมูลระยะไกลและเรียกใช้แบบสอบถาม SQL ในพวกเขา
ที่มา
(ที่มา: jackdb.com )
เมื่อเชื่อมต่อฐานข้อมูลแล้วคุณสามารถเรียกใช้แบบสอบถามและส่งออกเป็น CSV หรือ TXT (ดูด้านล่างขวา)
หมายเหตุ:ฉันไม่มีส่วนเกี่ยวข้องกับ JackDB ปัจจุบันฉันใช้บริการฟรีและคิดว่าเป็นผลิตภัณฑ์ที่ยอดเยี่ยม
ตามคำขอของ @ skeller88 ฉันจะโพสต์ความคิดเห็นของฉันใหม่เป็นคำตอบเพื่อไม่ให้คนที่อ่านคำตอบไม่หาย
ปัญหาเกี่ยวกับ DataGrip คือมันทำให้คุณเกาะติดกระเป๋าเงินของคุณ มันไม่ฟรี ลอง DBeaver รุ่นชุมชนที่ dbeaver.io มันเป็นเครื่องมือฐานข้อมูลแบบหลายแพลตฟอร์ม FOSS สำหรับโปรแกรมเมอร์ SQL, DBAs และนักวิเคราะห์ที่สนับสนุนฐานข้อมูลยอดนิยมทั้งหมด: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto ฯลฯ
DBeaver Community Edition ทำให้การเชื่อมต่อกับฐานข้อมูลออกแบบสอบถามเพื่อดึงข้อมูลจากนั้นดาวน์โหลดชุดผลลัพธ์เพื่อบันทึกลงใน CSV, JSON, SQL หรือรูปแบบข้อมูลทั่วไปอื่น ๆ มันเป็นคู่แข่ง FOSS ที่ทำงานได้เพื่อ TOAD สำหรับ Postgres, TOAD สำหรับ SQL Server หรือ Toad สำหรับ Oracle
ฉันไม่มีส่วนเกี่ยวข้องกับ DBeaver ฉันชอบราคาและฟังก์ชันการทำงาน แต่ฉันหวังว่าพวกเขาจะเปิดแอปพลิเคชัน DBeaver / Eclipse ให้มากขึ้นและทำให้ง่ายต่อการเพิ่มวิดเจ็ตการวิเคราะห์ลงใน DBeaver / Eclipse แทนที่จะต้องการให้ผู้ใช้ชำระค่าสมัครรายปีเพื่อสร้างกราฟและแผนภูมิโดยตรงภายใน แอปพลิเคชัน ทักษะการเขียนโค้ด Java ของฉันมีสนิมและฉันไม่รู้สึกอยากใช้เวลาหลายสัปดาห์เพื่อเรียนรู้วิธีสร้างวิดเจ็ต Eclipse เพียงเพื่อจะพบว่า DBeaver ได้ปิดการใช้งานความสามารถในการเพิ่มวิดเจ็ตบุคคลที่สามลงใน DBeaver Community Edition
ผู้ใช้ DBeaver มีข้อมูลเชิงลึกเกี่ยวกับขั้นตอนในการสร้างวิดเจ็ตการวิเคราะห์เพื่อเพิ่มลงใน Community Edition ของ DBeaver หรือไม่
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'