সিএসভি ফাইল থেকে শিরোনাম সহ পোস্টগ্রিএসকিউএল টেবিলে সিএসভি ফাইল থেকে কীভাবে অনুলিপি করবেন?


94

আমি একটি পোস্টগ্রিস টেবিলের একটি সিএসভি ফাইল অনুলিপি করতে চাই। এই টেবিলটিতে প্রায় 100 টি কলাম রয়েছে, তাই আমি যদি তা না করতে পারি তবে সেগুলি পুনরায় লিখতে চাই না।

আমি \copy table from 'table.csv' delimiter ',' csv;কমান্ডটি ব্যবহার করছি তবে একটি টেবিল তৈরি না করেই পেলাম ERROR: relation "table" does not exist। যদি আমি একটি ফাঁকা টেবিল যোগ করি তবে আমি কোনও ত্রুটি পাই না, তবে কিছুই হয় না। আমি এই কমান্ডটি দুই বা তিনবার চেষ্টা করেছি এবং কোনও আউটপুট বা বার্তা ছিল না, তবে আমি যখন পিজিএডমিনের মাধ্যমে এটি পরীক্ষা করেছি তখন টেবিলটি আপডেট করা হয়নি।

আমি করার চেষ্টা করছি এমন শিরোনাম সহ এমন কোনও টেবিল আমদানির কোনও উপায় আছে কি?


4
আপনার টেবিলের নাম table? খুবই বিভ্রান্তিকর. টেবিলটি বিদ্যমান আছে, বা আপনি এটি CSV এর উপর ভিত্তি করে তৈরি করতে চান? (আপনি পারবেন না)
ওয়াইল্ডপ্লাজার

4
ঠিক আছে, আমি এটির নাম দিয়েছি অন্য কিছু, তবে এই উদাহরণের জন্য এটি টেবিলে কল করতে দেয়। আমি চেষ্টা করেছিলাম এবং এটি বিদ্যমান ছাড়াও আমি চেষ্টা করেছি যে \copy table(column1, column2, ...) from 'table.csv' delimiter ',' csv;কোনও ভাগ্যও নয়। আদর্শভাবে সারণীটি একাই CSV এর মাধ্যমে তৈরি করা যেতে পারে এবং সেই ফাইলটিতে শিরোনাম ব্যবহার করা যেতে পারে।
স্ট্যানলে কাপ ফিল

সম্পর্কিত: স্ট্যাকওভারফ্লো
.

4
একটি বৃহত্তর সিএসভি পোস্ট পোস্টের টেবিলে রূপান্তর করার পরিকল্পনা করার জন্য কেবল একটি শীর্ষস্থানীয় - পোস্টগ্রিস একক টেবিলের 1600 কলামে ক্যাপড। আপনি 1600-কলাম-আকারেরগুলিতে টেবিলগুলি কাটাতে পারবেন না এবং তারপরে সেগুলিতে যোগদান করুন। আপনাকে ডিবি পুনরায় নকশা করা দরকার।
আচেকারউড

অজগর যদি আপনার কাছে উপলব্ধ থাকে তবে আপনি ডি 6 স্ট্যাক ব্যবহার করতে পারেন । এটি স্কিমা পরিবর্তনেরও যত্ন নেয়।
সিটিএনরম্যান

উত্তর:


135

এটি কাজ করে। প্রথম সারিতে এটিতে কলামের নাম ছিল।

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

4
আমি মনে করি এই কমান্ডটি নিয়ে সমস্যাটি হ'ল, আপনাকে ডিবি সুপারভাইজার হতে হবে। \ অনুলিপি সাধারণ ব্যবহারকারীর হিসাবেও কাজ করে
এক্সকোম

30
COPYএটি কোনও সারণী তৈরি করে না বা এতে কলাম যুক্ত করে না, এটি বিদ্যমান কলামগুলির সাথে একটি বিদ্যমান টেবিলটিতে সারি যুক্ত করে। সম্ভবত প্রশ্নকর্তা 100 ডলার কলাম তৈরি করতে স্বয়ংক্রিয় করতে চান COPYএবং কমপক্ষে PG 9.3 হিসাবে এই কার্যকারিতা নেই।
ড্যানিয়েল ভ্যারিট

4
@ এক্সোকম ভাল ক্যাচ যেহেতু আমি কখনই পোস্টগ্রিজ সিস্টেমে ডিবিগুলির জন্য প্রশাসক বা সুপারইউজার নই (প্যাগাডমিন আমাকে আমার যে ডেটাবেসগুলি ব্যবহার করেন সেগুলির মালিক করে তোলে এবং আমাকে সীমিত সুযোগ / ভূমিকা দেয়) অবশ্যই আমি "কপি" ব্যবহার করেছি। চিয়ার্স
জি সিটো

4
@ ড্যানিয়েল আমি বুঝতে পেরেছিলাম যে ব্যবহারকারীর টেবিলটি ইতিমধ্যে বিদ্যমান ছিল এবং তাদের প্রয়োজনীয় সমস্ত কলাম রয়েছে এবং তারা কেবল ডেটা চায়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')। এটি অতিরিক্ত ইনপুট ফাইলের ধরণের জন্যও এখানে এবং এখানে ডক্সের জন্য কাজ করে ।


4
আমি খুঁজে পেয়েছি যে পিডি.ডাটাফ্রেম.ফর্ম_সিএসভি আমাকে কম সমস্যা দেয় তবে এই উত্তরটি করা সহজতম উপায়, আইএমও।
ব্রক

সত্য, আমি pd.read_excelপরিবর্তে কেন টাইপ করেছি তা নিশ্চিত নই pd.read_csv। আমি উত্তর আপডেট।
joelostblom

4
এটি যখন আপনি একটি বৃহত সিএসভি ধারণ করবে এমন টেবিলটি প্রাক-তৈরি করতে চান না তখন এটির জন্য দুর্দান্ত সমাধান। যদিও কেবল শীর্ষস্থানীয় - পোস্টগ্রাগীরা কেবল একটি টেবিলের মধ্যে 1600 কলাম নিতে পারে। স্পষ্টতই অন্যান্য ডিবি ইঞ্জিনগুলি আরও বেশি অনুমতি দেবে। এই বহু কলাম থাকা আপাতদৃষ্টিতে দুর্বল এসকিউএল ফর্ম, যদিও এই sensক্যমত্যটি এপিডেমিওলজি থেকে ফিল্টার করতে পারেনি।
আচেকারউড

4
ডিফল্টরূপে df.to_sql()খুব স্লো হয়, এটির গতি বাড়ানোর জন্য আপনি ডি 6 স্ট্যাক ব্যবহার করতে পারেন । এটি স্কিমা পরিবর্তনেরও যত্ন নেয়।
সিটিএনরম্যান

13

বিনা অনুমতিতে টার্মিনাল দ্বারা বিকল্প

নোটস এ PG ডকুমেন্টেশন বলে

সার্ভার প্রক্রিয়াটির কার্যকারী ডিরেক্টরি (সাধারণত ক্লাস্টারের ডেটা ডিরেক্টরি) সম্পর্কিত, ক্লায়েন্টের ওয়ার্কিং ডিরেক্টরি নয়, পাথটির ব্যাখ্যা দেওয়া হবে।

সুতরাং, ভৌতিকভাবে, psqlকোনও স্থানীয় সার্ভারে এমনকি কোনও ক্লায়েন্ট ব্যবহার করেও আপনার সমস্যা রয়েছে ... এবং আপনি যদি অন্য ব্যবহারকারীর জন্য কপি আদেশটি প্রকাশ করেন, যেমন। গিথুব পড়ুন, পাঠকের সমস্যা হবে ...

ক্লায়েন্টের অনুমতি নিয়ে আপেক্ষিক পথটি প্রকাশের একমাত্র উপায় হল 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

আমি কোনও সমস্যা ছাড়াই কিছুক্ষণ এই ফাংশনটি ব্যবহার করে আসছি। আপনাকে কেবল সিএসভি ফাইলে থাকা সংখ্যা কলামগুলি সরবরাহ করতে হবে এবং এটি প্রথম সারির শিরোনামের নামগুলি নেবে এবং আপনার জন্য সারণী তৈরি করবে:

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';ক্ষেত্রে যা কিছু আছে তা পরিবর্তন করতে ভুলবেন না
মেহমেট

0

আপনি d6tstack ব্যবহার করতে পারেন যা আপনার জন্য সারণী তৈরি করে এবং pd.to_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')

এটি একাধিক সিএসভি আমদানি করার জন্য, ডেবি স্কেটিংয়ের আগে ডেটা স্কিমা পরিবর্তনগুলি এবং / অথবা পান্ডার (যেমন তারিখের জন্য) প্রিপ্রোসেসের সমাধানের জন্য দরকারী, উদাহরণ নোটবুকে আরও নীচে দেখুন

d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), 
    apply_after_read=apply_fun).to_psql_combine(uri_psql, 'table')
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.