CSV फ़ाइल में हेडर के साथ CSV फ़ाइल से PostgreSQL तालिका में प्रतिलिपि कैसे करें?


93

मैं एक CSV फ़ाइल को एक पोस्टग्रेज टेबल पर कॉपी करना चाहता हूं। इस तालिका में लगभग 100 कॉलम हैं, इसलिए यदि मुझे नहीं करना है तो मैं उन्हें फिर से लिखना नहीं चाहता।

मैं \copy table from 'table.csv' delimiter ',' csv;कमांड का उपयोग कर रहा हूं लेकिन बिना टेबल बनाए मुझे मिल रहा है ERROR: relation "table" does not exist। यदि मैं एक रिक्त तालिका जोड़ता हूं तो मुझे कोई त्रुटि नहीं मिलती है, लेकिन कुछ भी नहीं होता है। मैंने इस आदेश को दो या तीन बार आज़माया और कोई आउटपुट या संदेश नहीं था, लेकिन जब मैंने इसे पीजीएडमिन के माध्यम से जांचा तो टेबल अपडेट नहीं था।

क्या हेडर के साथ एक तालिका आयात करने का कोई तरीका है जैसे कि मैं करने की कोशिश कर रहा हूं?


2
आपकी तालिका का नाम है table? बहुत ज्यादा उलझन। क्या तालिका मौजूद है, या क्या आप इसे CSV के आधार पर बनाना चाहते हैं? (आप नहीं कर सकते हैं)
Wildplasser

1
ठीक है, मैंने इसे कुछ और नाम दिया है, लेकिन इस उदाहरण के लिए इसे टेबल कहते हैं। मैंने कोशिश की और इसके बिना विद्यमान मैंने भी बिना \copy table(column1, column2, ...) from 'table.csv' delimiter ',' csv;किसी भाग्य के साथ करने की कोशिश की । आदर्श रूप से तालिका अकेले CSV के माध्यम से बनाई जा सकती है, और उस फ़ाइल में हेडर का उपयोग कर सकते हैं।
स्टेनली कप फिल


2
एक बड़े सीएसवी को पोस्टग्रेज टेबल में बदलने की योजना बनाने वाले किसी भी व्यक्ति के लिए सिर्फ एक हेड - पोस्टग्रेज को एक सिंगल टेबल में 1600 कॉलम पर कैप किया गया है। आप 1600-कॉलम-आकार वाले लोगों में तालिकाओं को नहीं जोड़ सकते हैं और फिर उनके बाद जुड़ सकते हैं। आपको db को फिर से डिज़ाइन करना होगा।
अचौर्रौड

यदि अजगर आपके लिए उपलब्ध है, तो आप d6tstack का उपयोग कर सकते हैं । यह स्कीमा परिवर्तन का भी ध्यान रखता है।
शहरनुमा

जवाबों:


135

यह काम किया। पहली पंक्ति में कॉलम नाम थे।

COPY wheat FROM 'wheat_crop_data.csv' DELIMITER ';' CSV HEADER

5
मुझे लगता है कि इस कमांड के साथ समस्या यह है कि आपको DB सुपरयुसर होना होगा। \ copy सामान्य उपयोगकर्ता के रूप में भी काम करता है
13

29
COPYएक तालिका नहीं बनाता है या इसमें कॉलम नहीं जोड़ता है, यह अपने मौजूदा कॉलम के साथ मौजूदा तालिका में पंक्तियों को जोड़ता है। संभवत: पूछने वाला ~ 100 कॉलम के निर्माण को स्वचालित करना चाहता है, और COPYयह कार्यक्षमता नहीं है, जैसा कि पीजी 9.3 में कम से कम।
डेनियल वेरिटे जूल

2
@ अच्छी पकड़। चूंकि मैं पोस्टग्रेज सिस्टम पर उपयोग किए जाने वाले डीबी के लिए कभी भी एक व्यवस्थापक या सुपरयुसर नहीं हूं (पीजीडीमिन मुझे उन डेटाबेस का मालिक बनाता है जो मैं उपयोग करता हूं और मुझे सीमित विशेषाधिकार / भूमिका देता है) मैंने `\ COPY 'का उपयोग किया होगा। चीयर्स
जी। सीटीओ

2
@ डैनियल मैं समझता था कि उपयोगकर्ता की तालिका पहले से ही मौजूद थी और उनके पास आवश्यक सभी कॉलम थे और वे केवल ADDडेटा चाहते थे
जी। सीटो

syntax error at or near "HEADER" LINE 2: delimiter ',' CSV HEADERएम्स रेडशिफ्ट पर मिला ।
मिथिला

24

पायथन लाइब्रेरी के साथ pandas, आप आसानी से एक सीएसवी फ़ाइल से कॉलम नाम और अनुमानित डेटा प्रकार बना सकते हैं।

from sqlalchemy import create_engine
import pandas as pd

engine = create_engine('postgresql://user:pass@localhost/db_name')
df = pd.read_csv('/path/to/csv_file')
df.to_sql('pandas_db', engine)

if_existsपैरामीटर को बदलना या एक मौजूदा टेबल में संलग्न करने के लिए, उदाहरण के लिए सेट किया जा सकता df.to_sql('pandas_db', engine, if_exists='replace')। यह अतिरिक्त इनपुट फ़ाइल प्रकारों के लिए भी काम करता है, डॉक्स यहां और यहां


1
मुझे लगता है कि pd.DataFrame.from_csv मुझे कम परेशानी देता है, लेकिन यह उत्तर अब तक ऐसा करने का सबसे आसान तरीका है, IMO।
ब्रॉक

सच है, मुझे यकीन नहीं है कि मैंने क्यों टाइप किया pd.read_excel, इसके बजाय pd.read_csv। मैंने जवाब अपडेट किया।
joelostblom

1
यह एक शानदार समाधान है जब आप उस तालिका को पूर्व-निर्मित नहीं करना चाहते हैं जो एक बड़े सीएसवी को रखेगा। हालांकि एक सिर - हालांकि पोस्टग्रेज केवल एक टेबल में 1600 कॉलम ले सकते हैं। जाहिरा तौर पर अन्य DB इंजन अधिक की अनुमति देगा। यह कई कॉलम होने के कारण स्पष्ट रूप से खराब SQL रूप है, हालांकि इस सहमति को अभी तक महामारी विज्ञान के माध्यम से फ़िल्टर करना है।
15

1
डिफ़ॉल्ट रूप df.to_sql()से बहुत धीमी है, इस गति को बढ़ाने के लिए आप d6tstack का उपयोग कर सकते हैं । यह स्कीमा परिवर्तन का भी ध्यान रखता है।
शहरनर्मन

13

बिना किसी अनुमति के टर्मिनल द्वारा वैकल्पिक

नोट में स्नातकोत्तर प्रलेखन कहते हैं

पथ को सर्वर प्रक्रिया की कामकाजी निर्देशिका (सामान्य रूप से क्लस्टर की डेटा निर्देशिका) के सापेक्ष समझा जाएगा, न कि क्लाइंट की कार्यशील निर्देशिका।

इसलिए, स्थानीय रूप से, psqlकिसी भी क्लाइंट का उपयोग करते हुए , स्थानीय सर्वर में, आपको समस्याएँ हैं ... और, यदि आप अन्य उपयोगकर्ताओं के लिए COPY कमांड व्यक्त कर रहे हैं, जैसे। Github README में, पाठक को समस्याएं होंगी ...

क्लाइंट अनुमतियों के साथ रिश्तेदार पथ को व्यक्त करने का एकमात्र तरीका STDIN का उपयोग कर रहा है ,

जब STDIN या STDOUT निर्दिष्ट किया जाता है, तो डेटा क्लाइंट और सर्वर के बीच कनेक्शन के माध्यम से प्रेषित होता है।

जैसा कि यहाँ याद किया गया है :

psql -h remotehost -d remote_mydb -U myuser -c \
   "copy mytable (column1, column2) from STDIN with delimiter as ','" \
   < ./relative_path/file.csv

3

मैं कुछ समय के लिए बिना किसी समस्या के इस फ़ंक्शन का उपयोग कर रहा हूं। आपको सिर्फ़ csv फ़ाइल में मौजूद संख्या कॉलम प्रदान करने की आवश्यकता है, और यह पहली पंक्ति से हेडर नाम लेगा और आपके लिए तालिका बनाएगा:

create or replace function data.load_csv_file
    (
        target_table  text, -- name of the table that will be created
        csv_file_path text,
        col_count     integer
    )

    returns void

as $$

declare
    iter      integer; -- dummy integer to iterate columns with
    col       text; -- to keep column names in each iteration
    col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet

begin
    set schema 'data';

    create table temp_table ();

    -- add just enough number of columns
    for iter in 1..col_count
    loop
        execute format ('alter table temp_table add column col_%s text;', iter);
    end loop;

    -- copy the data from csv file
    execute format ('copy temp_table from %L with delimiter '','' quote ''"'' csv ', csv_file_path);

    iter := 1;
    col_first := (select col_1
                  from temp_table
                  limit 1);

    -- update the column names based on the first row which has the column names
    for col in execute format ('select unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from temp_table where col_1 = %L', col_first)
    loop
        execute format ('alter table temp_table rename column col_%s to %s', iter, col);
        iter := iter + 1;
    end loop;

    -- delete the columns row // using quote_ident or %I does not work here!?
    execute format ('delete from temp_table where %s = %L', col_first, col_first);

    -- change the temp table name to the name given as parameter, if not blank
    if length (target_table) > 0 then
        execute format ('alter table temp_table rename to %I', target_table);
    end if;
end;

$$ language plpgsql;

आपके set schema 'data';लिए जो भी मामला है उसे बदलने के लिए मत भूलना
mehmet

0

आप d6tstack का उपयोग कर सकते हैं जो आपके लिए तालिका बनाता है और pd.to_sql () की तुलना में तेज़ है क्योंकि यह मूल DB आयात आदेशों का उपयोग करता है। यह Postgres के साथ-साथ MYSQL और MS SQL को सपोर्ट करता है।

import pandas as pd
df = pd.read_csv('table.csv')
uri_psql = 'postgresql+psycopg2://usr:pwd@localhost/db'
d6tstack.utils.pd_to_psql(df, uri_psql, 'table')

यह कई CSV आयात करने के लिए उपयोगी है, डेटा स्कीमा परिवर्तन और / या पांडा के साथ प्रीप्रोसेस को हल करना (जैसे तारीखों के लिए) db को लिखने से पहले, उदाहरण नोटबुक में आगे देखें

d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), 
    apply_after_read=apply_fun).to_psql_combine(uri_psql, 'table')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.