使用csv中的副本时,从另一个表更新ID列

时间:2014-06-03 17:47:54

标签: copy postgresql-9.2 psql

我正在尝试使用csv文件中的COPY将数据导入表中。这是我要导入的表:

CREATE TABLE public.forms_member_registration
(
   baseformmodel_ptr_id integer NOT NULL,
   "Agrihub" character varying(200) NOT NULL,
   "Ward_Number" character varying(300) NOT NULL,
   "Area" character varying(300) NOT NULL,
   "First_Name" character varying(300) NOT NULL,
   "Last_Name" character varying(300) NOT NULL,
   "Other_Name" character varying(300) NOT NULL,
   -----------snip--------------------------------
   "L3_Modules_Completed" character varying(200),
   "L3_Specify_Other" character varying(300) NOT NULL,
   gps_location geometry(Point,4326),

   CONSTRAINT forms_member_registration_pkey 
      PRIMARY KEY (baseformmodel_ptr_id),
   CONSTRAINT baseformmodel_ptr_id_refs_id_c03f6c72 
      FOREIGN KEY (baseformmodel_ptr_id)
          REFERENCES public.forms_baseformmodel (id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)

主键是引用此表:

CREATE TABLE public.forms_baseformmodel
(
    id integer NOT NULL DEFAULT nextval('forms_baseformmodel_id_seq'::regclass),
    user_id integer NOT NULL,
    created_at timestamp with time zone NOT NULL,

    CONSTRAINT forms_baseformmodel_pkey 
        PRIMARY KEY (id),
    CONSTRAINT user_id_refs_id_3a410ec9 
        FOREIGN KEY (user_id)
           REFERENCES public.auth_user (id) MATCH SIMPLE
           ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)

我正在使用此复制命令:

COPY forms_member_registration("Agrihub", "Ward_Number", "Area","First_Name",        "Last_Name", "Other_Name", "SA_ID_Number", "Gender", "Phone_Number") FROM '/opt/project/migration/file-3.csv' DELIMITER ',' CSV HEADER;

给出此错误:

ERROR:  null value in column "baseformmodel_ptr_id" violates not-null constraint

所以我看到的问题是" baseform_ptr_id"需要从forms_baseformmodel表的id列中为每个条目检索,但只有在对forms_baseformmodel进行条目时才会创建id。

如何在forms_baseformmodel中创建条目,检索它并将其添加到要复制的元组中?

希望这是有道理的...这对我来说都是新的。

提前致谢

1 个答案:

答案 0 :(得分:0)

这是一个相当普遍的问题。你必须做的是:

  • COPY数据到TEMPORARYUNLOGGED表格;

  • INSERT INTO real_table SELECT ... FROM temp_table INNER JOIN other_table ...

换句话说,复制到临时表,然后使用连接生成实际数据集,并将连接产品insert生成到真实表中。

它是somewhat related to the bulk upsert problem

因此,在您的情况下,您需要在其中创建temp_forms_member_registrationcopy csv,包括您要替换的user_id列,然后:

INSERT INTO forms_member_registration(
  baseformmodel_ptr_id, 
  "Agrihub", 
  ...
)
SELECT 
  fbfm.id, 
  tfmr."Agrihub",
  ...
FROM temp_forms_member_registration tfmr
INNER JOIN forms_baseformmodel ON (tfmr.user_id = fbfm.user_id);