【问题标题】:Data extract and import from CSV with foreign keys - Postgresql使用外键从 CSV 提取和导入数据 - Postgresql
【发布时间】:2022-01-27 05:23:42
【问题描述】:

我有一个多租户数据库。我的要求是从数据库中提取单个租户的数据并插入到其他数据库中。

所以我有 2 个表:用户和身份。 用户表具有与身份表连接的外键 identity_id 一个客户下可以有多个身份和用户。

我正在将数据提取到 csv 文件并从 csv 文件插入到新数据库中。 主键设置为自动递增,因此用户和身份表在从 csv 插入数据时生成 id。

现有数据库中的表数据

用户表

| id  | identity_id |
| --- | ------------|
| 86  | 70          |
| 193 | 127         |
| 223 | 131         |

身份表

|id |name        |email            |
|---|------------|-----------------|
|70 |Alon muscle |muscle@test.com  |
|131|james       |james@james.com  |
|127|watson      |watson@watson.com|

现在 identity_id 是用户表映射到身份表的外键。

我正在尝试将用户和身份数据插入新数据库 因此,主键将为用户和身份自动递增。 问题来自外键。 我有多个用户和身份记录,如何维护 foreign_key 关系?

【问题讨论】:

  • 您缺少重要的必要信息。花几分钟时间回顾How to Ask。具体来说,更新您的问题以包括表定义 (ddl),包括 PK/FK、样本数据(作为 csv)以及该数据的预期结果。全部为文本 - 无图片.
  • 更新表格详情@Belayer
  • 我尝试将数据复制到临时表,但无法弄清楚如何使用该临时表来映射外键关系

标签: sql postgresql foreign-keys primary-key multi-tenant


【解决方案1】:

好吧,您实际上并没有提供有关表格的详细信息,那将是实际定义 (ddl)。也不提供 CVS 内容,我假设您的阶段表包含相同的内容。然而,根据提供的测试数据和几个假设,以下演示了一种加载数据的方法。方法是构建一个过程,使用 stage 表加载identities 表,然后从提供的电子邮件中选择生成的 id 来填充users 表。假设:

  1. identities 中的电子邮件必须是唯一的(至少小写)。
  2. 阶段表反映了identities 的姓名和电子邮件。

加载身份和用户的过程。

    create or replace procedure generate_user_idents() 
      language sql $
        insert into identities(name, email)
             select name, email
               from stage
              on conflict (low_email) 
                  do nothing ; 
                 
    as $$
        insert into users(ident_id) 
             select ident.ident_id 
               from identities ident 
              where ident.low_email in 
                    ( select lower(email) 
                        from stage
                    ) ;
                   
    $$;  

脚本清除和重新填充阶段数据,然后将阶段加载到身份和用户。

    do $$
    begin
        execute 'truncate table stage'; 
    
       -- replace the following with your \copy to load stage 
        insert into stage(name, email)
             values ( 'Alon muscle', 'muscle@test.com' )
                  , ( 'watson',      'watson@watson.com')         
                  , ( 'james',       'james@james.com' ); 
            
        call generate_user_idents(); 
    end ; 
    $$;
    

demo here。由于演示生成了 id,它与您提供的值不完全匹配,但很接近。就目前而言,如果您未能清除stage 表或在其中重新输入相同的值,该过程将很高兴生成重复项。你必须决定如何处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-01
    • 2016-11-12
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多