【问题标题】:How do I import a CSV file into two related PostgreSQL tables?如何将 CSV 文件导入两个相关的 PostgreSQL 表?
【发布时间】:2020-12-10 15:30:08
【问题描述】:

假设我有一个名为“objects.csv”(第一行 = 标题)的两列 CSV 文件,其中包含以下几行:

colour,object
red,apple
blue,sky
blue,sea
red,plane
green,grass
red,car
red,ship
blue,pool
blue,towel
red,raincoat
green,hat
green,jumper
green,lawnmower
red,strawberry
red,cherry
blue,icicle

我有一个数据库,其中包含使用以下 SQL 脚本创建的两个相关表:

CREATE TABLE public.colours (
    colour_id serial NOT NULL,
    colour text NOT NULL,
    CONSTRAINT colours_pkey PRIMARY KEY (colour_id)
);

CREATE TABLE public.objects (
    object_id serial NOT NULL,
    object text NOT NULL,
    CONSTRAINT objects_pkey PRIMARY KEY (object_id),
    objects_colour_id_fkey integer REFERENCES colours(colour_id)
);

colours 表包含以下值:

colour_id,colour
1,red
2,green
3,blue

我需要将 CSV 文件导入数据库,以便将第一个 CSV 列中的颜色值“替换”为颜色表中的关联外键,因此对象表将包含:

1,apple
3,sky
3,sea
1,plane
2,grass
1,car
1,ship
3,pool
3,towel
1,raincoat
2,hat
2,jumper
2,lawnmower
1,strawberry
1,cherry
3,icicle

它将一个平面文件导入到两个规范化的“相关”表中。

我该如何实现?

【问题讨论】:

    标签: database postgresql csv import foreign-keys


    【解决方案1】:

    我会创建一个登陆表并使用 psql \copy 命令来登陆数据:

    CREATE TABLE public.colours (
        colour_id serial NOT NULL,
        colour text NOT NULL,
        CONSTRAINT colours_pkey PRIMARY KEY (colour_id)
    );
    CREATE TABLE
    
    CREATE TABLE public.objects (
        object_id serial NOT NULL,
        object text NOT NULL,
        CONSTRAINT objects_pkey PRIMARY KEY (object_id),
        objects_colour_id_fkey integer REFERENCES colours(colour_id)
    );
    CREATE TABLE
    
    create table objects_landing (colour text, object text);
    CREATE TABLE
    \copy objects_landing from 'objects.csv' csv header;
    COPY 16
    
    insert into colours (colour)
    select distinct colour               
      from objects_landing  
     where not exists(
             select 1 from colours
              where colour = objects_landing.colour);
    INSERT 0 3
    
    insert into objects (object, objects_colour_id_fkey)
    select distinct l.object, c.colour_id
      from objects_landing l
           join colours c
             on c.colour = l.colour
     where not exists (select 1
                         from objects
                        where object = l.object
                          and objects_colour_id_fkey = c.colour_id);
    INSERT 0 16
    
    

    结果:

    select * from objects;
    ┌───────────┬────────────┬────────────────────────┐
    │ object_id │   object   │ objects_colour_id_fkey │
    ├───────────┼────────────┼────────────────────────┤
    │         1 │ apple      │                      3 │
    │         2 │ car        │                      3 │
    │         3 │ cherry     │                      3 │
    │         4 │ grass      │                      1 │
    │         5 │ hat        │                      1 │
    │         6 │ icicle     │                      2 │
    │         7 │ jumper     │                      1 │
    │         8 │ lawnmower  │                      1 │
    │         9 │ plane      │                      3 │
    │        10 │ pool       │                      2 │
    │        11 │ raincoat   │                      3 │
    │        12 │ sea        │                      2 │
    │        13 │ ship       │                      3 │
    │        14 │ sky        │                      2 │
    │        15 │ strawberry │                      3 │
    │        16 │ towel      │                      2 │
    └───────────┴────────────┴────────────────────────┘
    (16 rows)
    
    select * from colours;
    ┌───────────┬────────┐
    │ colour_id │ colour │
    ├───────────┼────────┤
    │         1 │ green  │
    │         2 │ blue   │
    │         3 │ red    │
    └───────────┴────────┘
    (3 rows)
    
    

    【讨论】:

    • 还没有听说过“登陆表”的想法。谢谢,会试试的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多