Copy from csv into table with id serial column auto-incrementing PSQL

白昼怎懂夜的黑 提交于 2020-01-06 11:50:47

问题


Looking for a parse solution that copies from CSV into my database with the end result of serial ID's generated. Either on the backend, or upon copying. As is, my ID's are null after the copy.

echo CREATE TABLE IF NOT EXISTS qs_facts_template (id SERIAL NOT NULL, symbol varchar(8), timestamp date, close real null, open real null, high real null, low real null, volume real null, CONSTRAINT qs_facts_template_key PRIMARY KEY (id)) WITH (OIDS=TRUE) TABLESPACE pg_default; ALTER TABLE qs_facts_template OWNER to postgres; | psql -U postgres -h %host% readyloop

echo CREATE TABLE IF NOT EXISTS qs_facts AS select * from qs_facts_template;| psql -U postgres -h %host% readyloop

echo \copy qs_facts (symbol, timestamp, close, open, high, low, volume) from PROGRAM 'cat C:\Users\user\Documents\quantshare\quotes.csv' DELIMITER ';' CSV HEADER| psql -U postgres -h %host% %dbName%

this post: https://unix.stackexchange.com/questions/277080/copy-csv-data-while-simultaneously-filling-serial-column did not solve my issue. I used the command mentioned by Guido and got the copy to work, but the id's are all null.

I was thinking maybe I could set the values AFTER the copy.


回答1:


You could write a BEFORE trigger:

CREATE FUNCTION id_trigger() RETURNS trigger
   LANGUAGE plpgsql AS
$$BEGIN
   NEW.id = nextval(pg_get_serial_sequence(TG_ARGV[0], 'id'));
   RETURN NEW;
END;$$;

CREATE TRIGGER id_trigger BEFORE INSERT ON qs_facts_template
   FOR EACH ROW EXECUTE PROCEDURE id_trigger('qs_facts_template');



回答2:


Problem is copy doesn't copy everything other than columns, add to the fact that you can't alter a table to serial.

So I exported the script in pg4admin from the original template table and was able to derive this which worked

    echo DROP materialized view if exists mv_qs_facts cascade| psql -U postgres -h %host% %dbName%
    echo DROP materialized view if exists mv_qs_symbols cascade| psql -U postgres -h %host% %dbName%

    echo DROP TABLE if exists qs_facts cascade| psql -U postgres -h %host% %dbName%

    echo drop table if exists qs_facts_template CASCADE;| psql -U postgres -h %host% readyloop
Rem create qs_fact table    
    echo CREATE TABLE IF NOT EXISTS qs_facts_template (id SERIAL, symbol varchar(8), timestamp date, close real null, open real null, high real null, low real null, volume real null, CONSTRAINT qs_facts_template_key PRIMARY KEY (id)) WITH (OIDS=TRUE) TABLESPACE pg_default; ALTER TABLE qs_facts_template OWNER to postgres; | psql -U postgres -h %host% readyloop

    echo CREATE TABLE IF NOT EXISTS qs_facts AS select * from qs_facts_template; | psql -U postgres -h %host% readyloop

    echo ALTER TABLE public.qs_facts ADD CONSTRAINT qs_facts_key PRIMARY KEY (id); | psql -U postgres -h %host% readyloop

    REM I looked at psqladmin and exported the sequence from qs_facts_template
    REM http://www.postgresqltutorial.com/postgresql-serial/
    echo CREATE SEQUENCE public.qs_facts_id_seq INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1; ALTER SEQUENCE public.qs_facts_id_seq OWNER TO postgres;| psql -U postgres -h %host% readyloop

    echo ALTER TABLE public.qs_facts ALTER COLUMN id SET DEFAULT nextval('qs_facts_id_seq'); | psql -U postgres -h %host% readyloop


来源:https://stackoverflow.com/questions/57751415/copy-from-csv-into-table-with-id-serial-column-auto-incrementing-psql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!