it-swarm.dev

كيف تنسخ من ملف CSV إلى جدول PostgreSQL برؤوس في ملف CSV؟

أريد نسخ ملف CSV إلى جدول Postgres. يوجد حوالي 100 عمود في هذا الجدول ، لذلك لا أرغب في إعادة كتابتها إذا لم أكن مضطرًا لذلك.

أنا أستخدم الأمر \copy table from 'table.csv' delimiter ',' csv; لكن بدون إنشاء جدول أحصل على ERROR: relation "table" does not exist. إذا أضفت طاولة فارغة ، فلن أحصل على أي خطأ ، لكن لا شيء يحدث. جربت هذا الأمر مرتين أو ثلاث مرات ولم يكن هناك أي إخراج أو رسائل ، لكن لم يتم تحديث الجدول عندما راجعت من خلال PGAdmin.

هل هناك طريقة لاستيراد جدول يتضمن الرؤوس كما أحاول القيام به؟

67
Stanley Cup Phil

هذا يعمل. كان للصف الأول أسماء الأعمدة فيه.

COPY wheat FROM 'wheat_crop_data.csv' DELIMITER ';' CSV HEADER
96
G. Cito

باستخدام مكتبة Python pandas ، يمكنك بسهولة إنشاء أسماء الأعمدة واستنتاج أنواع البيانات من ملف CSV.

from sqlalchemy import create_engine
import pandas as pd

engine = create_engine('postgresql://user:[email protected]/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'). هذا يعمل لأنواع ملفات الإدخال الإضافية كذلك ، docs هنا و هنا .

22
joelostblom

بديل عن طريق محطة دون إذن

pg الوثائق في NOTES يقول

سيتم تفسير المسار بالنسبة إلى دليل العمل لعملية الخادم (عادةً دليل بيانات المجموعة) ، وليس دليل عمل العميل.

لذلك ، بشكل عام ، باستخدام 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
9
Peter Krauss

لقد تم استخدام هذه الوظيفة لفترة من الوقت دون أي مشاكل. تحتاج فقط إلى توفير أعمدة الأرقام الموجودة في ملف 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;
3
mehmet

يمكنك استخدام d6tstack الذي ينشئ الجدول لك وهو أسرع من pd.to_sql () لأنه يستخدم أوامر استيراد DB الأصلية. وهو يدعم Postgres وكذلك MYSQL و MS SQL.

import pandas as pd
df = pd.read_csv('table.csv')
uri_psql = 'postgresql+psycopg2://usr:[email protected]/db'
d6tstack.utils.pd_to_psql(df, uri_psql, 'table')

كما أنها مفيدة لاستيراد ملفات CSV متعددة ، و/أو حل تغييرات مخطط البيانات و/أو المعالجة المسبقة مع الباندا (على سبيل المثال ، للتواريخ) قبل الكتابة إلى ديسيبل ، راجع المزيد في أمثلة على دفتر الملاحظات

d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), 
    apply_after_read=apply_fun).to_psql_combine(uri_psql, 'table')
0
citynorman