Can I automatically create a table in PostgreSQL from a csv file with headers?











up vote
34
down vote

favorite
8












I'm running PostgreSQL 9.2.6 on OS X 10.6.8. I would like to import data from a CSV file with column headers into a database. I can do this with the COPY statement, but only if I first manually create a table with a column for each column in the CSV file. Is there any way to automatically create this table based on the headers in the CSV file?



Per this question I have tried



COPY test FROM '/path/to/test.csv' CSV HEADER;



But I just get this error:



ERROR: relation "test" does not exist



And if I first create a table with no columns:



CREATE TABLE test ();



I get:



ERROR: extra data after last expected column



I can't find anything in the PostgreSQL COPY documentation about automatically creating a table. Is there some other way to automatically create a table from a CSV file with headers?










share|improve this question




























    up vote
    34
    down vote

    favorite
    8












    I'm running PostgreSQL 9.2.6 on OS X 10.6.8. I would like to import data from a CSV file with column headers into a database. I can do this with the COPY statement, but only if I first manually create a table with a column for each column in the CSV file. Is there any way to automatically create this table based on the headers in the CSV file?



    Per this question I have tried



    COPY test FROM '/path/to/test.csv' CSV HEADER;



    But I just get this error:



    ERROR: relation "test" does not exist



    And if I first create a table with no columns:



    CREATE TABLE test ();



    I get:



    ERROR: extra data after last expected column



    I can't find anything in the PostgreSQL COPY documentation about automatically creating a table. Is there some other way to automatically create a table from a CSV file with headers?










    share|improve this question


























      up vote
      34
      down vote

      favorite
      8









      up vote
      34
      down vote

      favorite
      8






      8





      I'm running PostgreSQL 9.2.6 on OS X 10.6.8. I would like to import data from a CSV file with column headers into a database. I can do this with the COPY statement, but only if I first manually create a table with a column for each column in the CSV file. Is there any way to automatically create this table based on the headers in the CSV file?



      Per this question I have tried



      COPY test FROM '/path/to/test.csv' CSV HEADER;



      But I just get this error:



      ERROR: relation "test" does not exist



      And if I first create a table with no columns:



      CREATE TABLE test ();



      I get:



      ERROR: extra data after last expected column



      I can't find anything in the PostgreSQL COPY documentation about automatically creating a table. Is there some other way to automatically create a table from a CSV file with headers?










      share|improve this question















      I'm running PostgreSQL 9.2.6 on OS X 10.6.8. I would like to import data from a CSV file with column headers into a database. I can do this with the COPY statement, but only if I first manually create a table with a column for each column in the CSV file. Is there any way to automatically create this table based on the headers in the CSV file?



      Per this question I have tried



      COPY test FROM '/path/to/test.csv' CSV HEADER;



      But I just get this error:



      ERROR: relation "test" does not exist



      And if I first create a table with no columns:



      CREATE TABLE test ();



      I get:



      ERROR: extra data after last expected column



      I can't find anything in the PostgreSQL COPY documentation about automatically creating a table. Is there some other way to automatically create a table from a CSV file with headers?







      postgresql csv






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 23 '17 at 11:54









      Community

      11




      11










      asked Jan 9 '14 at 10:57









      ihough

      183128




      183128
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          20
          down vote



          accepted










          You can't find anything in the COPY documentation, because COPY cannot create a table for you.

          You need to do that before you can COPY to it.






          share|improve this answer




























            up vote
            26
            down vote













            There is a very good tool that imports tables into Postgres from a csv file.
            It is a command-line tool called pgfutter (with binaries for windows, linux, etc.). One of its big advantages is that it recognizes the attribute/column names as well.



            The usage of the tool is simple. For example if you'd like to import myCSVfile.csv:



            pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv


            This will create a table (called myCSVfile) with the column names taken from the csv file's header. Additionally the data types will be identified from the existing data.



            A few notes: The command pgfutter varies depending on the binary you use, e.g. it could be pgfutter_windows_amd64.exe (rename it if you intend to use this command frequently). The above command has to be executed in a command line window (e.g. in Windows run cmd and ensure pgfutter is accessible). If you'd like to have a different table name add --table "myTable"; to select a particular database schema us --schema "mySchema". In case you are accessing an external database use --host "myHostDomain".



            A more elaborate example of pgfutter to import myFile into myTable is this one:



            pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv


            Most likely you will change a few data types (from text to numeric) after the import:



            alter table myTable
            alter column myColumn type numeric
            using (trim(myColumn)::numeric)





            share|improve this answer























            • I requires the destination table and columns to be created if I specify a schema name. Frustrating
              – Muhammad Gelbana
              Jul 28 '17 at 15:28










            • This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
              – Luís de Sousa
              Jul 16 at 12:34


















            up vote
            12
            down vote













            There is a second approach, which I found here (from mmatt). Basically you call a function within Postgres (last argument specifies the number of columns).



            select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)


            Here is mmatt's function code, which I had to modify slightly, because I am working on the public schema. (copy&paste into PgAdmin SQL Editor and run it to create the function)



            CREATE OR REPLACE FUNCTION load_csv_file(
            target_table text,
            csv_path text,
            col_count integer)
            RETURNS void AS
            $BODY$

            declare

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

            begin
            set schema 'public';

            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_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
            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;

            $BODY$
            LANGUAGE plpgsql VOLATILE
            COST 100;
            ALTER FUNCTION load_csv_file(text, text, integer)
            OWNER TO postgres;


            Note: There is a common issue with importing text files related to encoding. The csv file should be in UTF-8 format. However, sometimes this is not quite achieved by the programs, which try to do the encoding. I have overcome this issue by opening the file in Notepad++ and converting it to ANSI and back to UTF8.






            share|improve this answer



















            • 2




              This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
              – GT.
              Sep 15 '16 at 23:58











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f21018256%2fcan-i-automatically-create-a-table-in-postgresql-from-a-csv-file-with-headers%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            20
            down vote



            accepted










            You can't find anything in the COPY documentation, because COPY cannot create a table for you.

            You need to do that before you can COPY to it.






            share|improve this answer

























              up vote
              20
              down vote



              accepted










              You can't find anything in the COPY documentation, because COPY cannot create a table for you.

              You need to do that before you can COPY to it.






              share|improve this answer























                up vote
                20
                down vote



                accepted







                up vote
                20
                down vote



                accepted






                You can't find anything in the COPY documentation, because COPY cannot create a table for you.

                You need to do that before you can COPY to it.






                share|improve this answer












                You can't find anything in the COPY documentation, because COPY cannot create a table for you.

                You need to do that before you can COPY to it.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 9 '14 at 11:05









                Erwin Brandstetter

                335k64606785




                335k64606785
























                    up vote
                    26
                    down vote













                    There is a very good tool that imports tables into Postgres from a csv file.
                    It is a command-line tool called pgfutter (with binaries for windows, linux, etc.). One of its big advantages is that it recognizes the attribute/column names as well.



                    The usage of the tool is simple. For example if you'd like to import myCSVfile.csv:



                    pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv


                    This will create a table (called myCSVfile) with the column names taken from the csv file's header. Additionally the data types will be identified from the existing data.



                    A few notes: The command pgfutter varies depending on the binary you use, e.g. it could be pgfutter_windows_amd64.exe (rename it if you intend to use this command frequently). The above command has to be executed in a command line window (e.g. in Windows run cmd and ensure pgfutter is accessible). If you'd like to have a different table name add --table "myTable"; to select a particular database schema us --schema "mySchema". In case you are accessing an external database use --host "myHostDomain".



                    A more elaborate example of pgfutter to import myFile into myTable is this one:



                    pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv


                    Most likely you will change a few data types (from text to numeric) after the import:



                    alter table myTable
                    alter column myColumn type numeric
                    using (trim(myColumn)::numeric)





                    share|improve this answer























                    • I requires the destination table and columns to be created if I specify a schema name. Frustrating
                      – Muhammad Gelbana
                      Jul 28 '17 at 15:28










                    • This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                      – Luís de Sousa
                      Jul 16 at 12:34















                    up vote
                    26
                    down vote













                    There is a very good tool that imports tables into Postgres from a csv file.
                    It is a command-line tool called pgfutter (with binaries for windows, linux, etc.). One of its big advantages is that it recognizes the attribute/column names as well.



                    The usage of the tool is simple. For example if you'd like to import myCSVfile.csv:



                    pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv


                    This will create a table (called myCSVfile) with the column names taken from the csv file's header. Additionally the data types will be identified from the existing data.



                    A few notes: The command pgfutter varies depending on the binary you use, e.g. it could be pgfutter_windows_amd64.exe (rename it if you intend to use this command frequently). The above command has to be executed in a command line window (e.g. in Windows run cmd and ensure pgfutter is accessible). If you'd like to have a different table name add --table "myTable"; to select a particular database schema us --schema "mySchema". In case you are accessing an external database use --host "myHostDomain".



                    A more elaborate example of pgfutter to import myFile into myTable is this one:



                    pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv


                    Most likely you will change a few data types (from text to numeric) after the import:



                    alter table myTable
                    alter column myColumn type numeric
                    using (trim(myColumn)::numeric)





                    share|improve this answer























                    • I requires the destination table and columns to be created if I specify a schema name. Frustrating
                      – Muhammad Gelbana
                      Jul 28 '17 at 15:28










                    • This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                      – Luís de Sousa
                      Jul 16 at 12:34













                    up vote
                    26
                    down vote










                    up vote
                    26
                    down vote









                    There is a very good tool that imports tables into Postgres from a csv file.
                    It is a command-line tool called pgfutter (with binaries for windows, linux, etc.). One of its big advantages is that it recognizes the attribute/column names as well.



                    The usage of the tool is simple. For example if you'd like to import myCSVfile.csv:



                    pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv


                    This will create a table (called myCSVfile) with the column names taken from the csv file's header. Additionally the data types will be identified from the existing data.



                    A few notes: The command pgfutter varies depending on the binary you use, e.g. it could be pgfutter_windows_amd64.exe (rename it if you intend to use this command frequently). The above command has to be executed in a command line window (e.g. in Windows run cmd and ensure pgfutter is accessible). If you'd like to have a different table name add --table "myTable"; to select a particular database schema us --schema "mySchema". In case you are accessing an external database use --host "myHostDomain".



                    A more elaborate example of pgfutter to import myFile into myTable is this one:



                    pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv


                    Most likely you will change a few data types (from text to numeric) after the import:



                    alter table myTable
                    alter column myColumn type numeric
                    using (trim(myColumn)::numeric)





                    share|improve this answer














                    There is a very good tool that imports tables into Postgres from a csv file.
                    It is a command-line tool called pgfutter (with binaries for windows, linux, etc.). One of its big advantages is that it recognizes the attribute/column names as well.



                    The usage of the tool is simple. For example if you'd like to import myCSVfile.csv:



                    pgfutter --db "myDatabase" --port "5432" --user "postgres" --pw "mySecretPassword" csv myCSVfile.csv


                    This will create a table (called myCSVfile) with the column names taken from the csv file's header. Additionally the data types will be identified from the existing data.



                    A few notes: The command pgfutter varies depending on the binary you use, e.g. it could be pgfutter_windows_amd64.exe (rename it if you intend to use this command frequently). The above command has to be executed in a command line window (e.g. in Windows run cmd and ensure pgfutter is accessible). If you'd like to have a different table name add --table "myTable"; to select a particular database schema us --schema "mySchema". In case you are accessing an external database use --host "myHostDomain".



                    A more elaborate example of pgfutter to import myFile into myTable is this one:



                    pgfutter --host "localhost" --port "5432" --db "myDB" --schema "public" --table "myTable" --user "postgres" --pw "myPwd" csv myFile.csv


                    Most likely you will change a few data types (from text to numeric) after the import:



                    alter table myTable
                    alter column myColumn type numeric
                    using (trim(myColumn)::numeric)






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 19 '16 at 18:48

























                    answered Jan 19 '16 at 16:50









                    Wolfi

                    58767




                    58767












                    • I requires the destination table and columns to be created if I specify a schema name. Frustrating
                      – Muhammad Gelbana
                      Jul 28 '17 at 15:28










                    • This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                      – Luís de Sousa
                      Jul 16 at 12:34


















                    • I requires the destination table and columns to be created if I specify a schema name. Frustrating
                      – Muhammad Gelbana
                      Jul 28 '17 at 15:28










                    • This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                      – Luís de Sousa
                      Jul 16 at 12:34
















                    I requires the destination table and columns to be created if I specify a schema name. Frustrating
                    – Muhammad Gelbana
                    Jul 28 '17 at 15:28




                    I requires the destination table and columns to be created if I specify a schema name. Frustrating
                    – Muhammad Gelbana
                    Jul 28 '17 at 15:28












                    This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                    – Luís de Sousa
                    Jul 16 at 12:34




                    This tool is presently failing with an "index out of range" exception when you try to import a CSV file.
                    – Luís de Sousa
                    Jul 16 at 12:34










                    up vote
                    12
                    down vote













                    There is a second approach, which I found here (from mmatt). Basically you call a function within Postgres (last argument specifies the number of columns).



                    select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)


                    Here is mmatt's function code, which I had to modify slightly, because I am working on the public schema. (copy&paste into PgAdmin SQL Editor and run it to create the function)



                    CREATE OR REPLACE FUNCTION load_csv_file(
                    target_table text,
                    csv_path text,
                    col_count integer)
                    RETURNS void AS
                    $BODY$

                    declare

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

                    begin
                    set schema 'public';

                    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_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
                    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;

                    $BODY$
                    LANGUAGE plpgsql VOLATILE
                    COST 100;
                    ALTER FUNCTION load_csv_file(text, text, integer)
                    OWNER TO postgres;


                    Note: There is a common issue with importing text files related to encoding. The csv file should be in UTF-8 format. However, sometimes this is not quite achieved by the programs, which try to do the encoding. I have overcome this issue by opening the file in Notepad++ and converting it to ANSI and back to UTF8.






                    share|improve this answer



















                    • 2




                      This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                      – GT.
                      Sep 15 '16 at 23:58















                    up vote
                    12
                    down vote













                    There is a second approach, which I found here (from mmatt). Basically you call a function within Postgres (last argument specifies the number of columns).



                    select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)


                    Here is mmatt's function code, which I had to modify slightly, because I am working on the public schema. (copy&paste into PgAdmin SQL Editor and run it to create the function)



                    CREATE OR REPLACE FUNCTION load_csv_file(
                    target_table text,
                    csv_path text,
                    col_count integer)
                    RETURNS void AS
                    $BODY$

                    declare

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

                    begin
                    set schema 'public';

                    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_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
                    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;

                    $BODY$
                    LANGUAGE plpgsql VOLATILE
                    COST 100;
                    ALTER FUNCTION load_csv_file(text, text, integer)
                    OWNER TO postgres;


                    Note: There is a common issue with importing text files related to encoding. The csv file should be in UTF-8 format. However, sometimes this is not quite achieved by the programs, which try to do the encoding. I have overcome this issue by opening the file in Notepad++ and converting it to ANSI and back to UTF8.






                    share|improve this answer



















                    • 2




                      This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                      – GT.
                      Sep 15 '16 at 23:58













                    up vote
                    12
                    down vote










                    up vote
                    12
                    down vote









                    There is a second approach, which I found here (from mmatt). Basically you call a function within Postgres (last argument specifies the number of columns).



                    select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)


                    Here is mmatt's function code, which I had to modify slightly, because I am working on the public schema. (copy&paste into PgAdmin SQL Editor and run it to create the function)



                    CREATE OR REPLACE FUNCTION load_csv_file(
                    target_table text,
                    csv_path text,
                    col_count integer)
                    RETURNS void AS
                    $BODY$

                    declare

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

                    begin
                    set schema 'public';

                    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_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
                    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;

                    $BODY$
                    LANGUAGE plpgsql VOLATILE
                    COST 100;
                    ALTER FUNCTION load_csv_file(text, text, integer)
                    OWNER TO postgres;


                    Note: There is a common issue with importing text files related to encoding. The csv file should be in UTF-8 format. However, sometimes this is not quite achieved by the programs, which try to do the encoding. I have overcome this issue by opening the file in Notepad++ and converting it to ANSI and back to UTF8.






                    share|improve this answer














                    There is a second approach, which I found here (from mmatt). Basically you call a function within Postgres (last argument specifies the number of columns).



                    select load_csv_file('myTable','C:/MyPath/MyFile.csv',24)


                    Here is mmatt's function code, which I had to modify slightly, because I am working on the public schema. (copy&paste into PgAdmin SQL Editor and run it to create the function)



                    CREATE OR REPLACE FUNCTION load_csv_file(
                    target_table text,
                    csv_path text,
                    col_count integer)
                    RETURNS void AS
                    $BODY$

                    declare

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

                    begin
                    set schema 'public';

                    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_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
                    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;

                    $BODY$
                    LANGUAGE plpgsql VOLATILE
                    COST 100;
                    ALTER FUNCTION load_csv_file(text, text, integer)
                    OWNER TO postgres;


                    Note: There is a common issue with importing text files related to encoding. The csv file should be in UTF-8 format. However, sometimes this is not quite achieved by the programs, which try to do the encoding. I have overcome this issue by opening the file in Notepad++ and converting it to ANSI and back to UTF8.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited May 23 '17 at 11:46









                    Community

                    11




                    11










                    answered Jan 19 '16 at 18:45









                    Wolfi

                    58767




                    58767








                    • 2




                      This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                      – GT.
                      Sep 15 '16 at 23:58














                    • 2




                      This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                      – GT.
                      Sep 15 '16 at 23:58








                    2




                    2




                    This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                    – GT.
                    Sep 15 '16 at 23:58




                    This is a tidy solution. Take care to ensure that none of the columns have reserved keyword names - e.g., if the CSV file has a column called order (for order numbers, say) change it to order_num. Also, remember to change column TYPE as required.
                    – GT.
                    Sep 15 '16 at 23:58


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f21018256%2fcan-i-automatically-create-a-table-in-postgresql-from-a-csv-file-with-headers%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Ottavio Pratesi

                    Tricia Helfer

                    15 giugno