【问题标题】:Copy a table from one database to another in Postgres在 Postgres 中将表从一个数据库复制到另一个数据库
【发布时间】:2011-03-12 19:52:25
【问题描述】:

我试图在 Postgres 中将整个表从一个数据库复制到另一个数据库。有什么建议吗?

【问题讨论】:

  • 如果您可以安装 DBeaver,它有一种非常简单的方法可以在您连接的两个数据库之间进行传输。只需右键单击源表并选择导出数据,定位数据库表并将目标设置为目标数据库。

标签: postgresql


【解决方案1】:

您可以通过两个简单的步骤

# dump the database in custom-format archive
pg_dump -Fc mydb > db.dump

# restore the database
pg_restore -d newdb db.dump

如果是远程数据库

# dump the database in custom-format archive
pg_dump -U mydb_user -h mydb_host -t table_name -Fc mydb > db.dump

# restore the database
pg_restore -U newdb_user -h newdb_host -d newdb db.dump

【讨论】:

    【解决方案2】:

    提取表并将其直接通过管道传输到目标数据库:

    pg_dump -t table_to_copy source_db | psql target_db
    

    注意:如果其他数据库已经建立了表,你应该使用-a标志只导入数据,否则你可能会看到像“内存不足”这样的奇怪错误:

    pg_dump -a -t table_to_copy source_db | psql target_db
    

    【讨论】:

    • 这将如何用于远程数据库链接?例如,我需要从不同的位置转储。
    • @curlyreggie 没有尝试过这个,但我看不出它为什么不起作用。尝试将用户和服务器细节添加到命令中,例如 pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
    • 你可以试试这个:“pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db -U remote_user -h remote_server”
    • 请注意,如果其他数据库已经设置了表,您应该为 data only 使用-a 标志。即pg_dump -a -t my_table my_db | psql target_db。当我在这里时,如果您的数据库在服务器上,我发现将数据库转储到文件然后将该文件 scp 到数据库,然后将文件的内容发送到 psql 会更容易。例如pg_dump -a -t my_table my_db > my_file.sql 并将其放在您的服务器上之后 --> psql my_other_db < my_file.sql
    • @EamonnKenny 转储一个区分大小写的表,执行:pg_dump -t '"tableToCopy"' source_db | psql target_db。请注意,单引号和双引号将表名括起来
    【解决方案3】:

    对于DBeaver tool 用户,您可以“导出数据”到另一个数据库中的表。

    我一直面临的唯一错误是因为wrong postgres driver

    SQL Error [34000]: ERROR: portal "c_2" does not exist
        ERROR: Invalid protocol sequence 'P' while in PortalSuspended state.
    

    这是一个关于如何导出数据的官方 wikihttps://github.com/dbeaver/dbeaver/wiki/Data-transfer

    【讨论】:

      【解决方案4】:

      使用dblink会更方便!

      truncate table tableA;
      
      insert into tableA
      select *
      from dblink('hostaddr=xxx.xxx.xxx.xxx dbname=mydb user=postgres',
                  'select a,b from tableA')
             as t1(a text,b text);
      

      【讨论】:

      • 为什么两个 dbname 在两次..?哪一个是源和目标?
      • 我们插入的tableA是目标,dbLink中的tableA是源。
      • 如果我要使用dblink bun我不知道源源表的结构?
      • @Ossarotte 嘿,你找到问题的答案了吗?
      【解决方案5】:

      我使用的是 DataGrip(由 Intellij Idea 提供)。并且很容易将数据从一个表(在不同的数据库中复制到另一个)。

      首先,确保您已连接到 Data Grip 中的两个数据源。

      选择源表并按 F5 或(右键单击 -> 选择将表复制到。)

      这将显示所有表格的列表(您也可以在弹出窗口中使用表格名称进行搜索)。只需选择您的目标,然后按 OK。

      DataGrip 将为您处理所有其他事情。

      【讨论】:

      • 请注意,DataGrip 不是免费的!
      • 此功能也是 IntelliJ Ultimate 的一部分(也不是免费的),但很多人可能已经拥有。
      【解决方案6】:

      在连接到两台服务器的 Linux 主机上使用 psql

      ( export PGPASSWORD=password1 
        psql -U user1 -h host1 database1 \
        -c "copy (select field1,field2 from table1) to stdout with csv" ) \
      | 
      ( export PGPASSWORD=password2 
        psql -U user2 -h host2 database2 \ 
         -c "copy table2 (field1, field2) from stdin csv" )
      

      【讨论】:

      • 不需要导出,PGPASSWORD=password1 psql -U ... 那么你甚至不需要显式的子shell!通常,您首先需要做几件事来设置,因此无论如何可能需要子shell。此外,密码不会导出到后续进程中。谢谢!
      • @LimitedAtonement 实际上你是对的,export 和 subshel​​ls 不是必需的。它只是更复杂脚本的一部分,即使我没有尝试没有导出和子shell,所以,我提供它只是为了诚实并提供有效的解决方案
      • 该表必须存在于目标数据库中。要创建它,请尝试pg_dump -t '<table_name>' --schema-only
      • 将密码输入~/.pgpass
      【解决方案7】:

      作为替代方案,您还可以使用外部数据包装器扩展将远程表公开为本地表。然后,您可以通过从远程数据库中的表中进行选择来插入表中。唯一的缺点是速度不是很快。

      【讨论】:

        【解决方案8】:

        如果您从 Windows 运行 pgAdmin(备份:pg_dump,还原:pg_restore),它将尝试默认将文件输出到 c:\Windows\System32,这就是为什么您会收到 Permission/Access denied 错误,而不是因为用户 postgres 不够高。 以管理员身份运行 pgAdmin 或仅选择 Windows 系统文件夹以外的输出位置。

        【讨论】:

          【解决方案9】:

          第一install dblink

          然后,你会做这样的事情:

          INSERT INTO t2 select * from 
          dblink('host=1.2.3.4
           user=*****
           password=******
           dbname=D1', 'select * t1') tt(
                 id int,
            col_1 character varying,
            col_2 character varying,
            col_3 int,
            col_4 varchar 
          );
          

          【讨论】:

          • 这个答案很棒,因为它允许过滤复制的行(在 dblink 第二个参数中添加 WHERE 子句)。但是,需要明确列名(Postgres 9.4),例如:INSERT INTO l_tbl (l_col1, l_col2, l_col3) SELECT * FROM dblink('dbname=r_db hostaddr=r_ip password=r_pass user=r_usr', 'select r_col1, r_col2, r_col3 from r_tbl where r_col1 between ''2015-10-29'' AND ''2015-10-30'' ') AS t1(col1 MACADDR, col2 TIMESTAMP, col3 NUMERIC(7,1));(l 表示本地,r 是远程。转义单引号。提供 col 类型。)
          【解决方案10】:

          pg_dump 并不总是有效。

          鉴于您在两个数据库中都有相同的表 ddl 您可以按如下方式从标准输出和标准输入破解它:

           # grab the list of cols straight from bash
          
           psql -d "$src_db" -t -c \
           "SELECT column_name 
           FROM information_schema.columns 
           WHERE 1=1 
           AND table_name='"$table_to_copy"'"
           # ^^^ filter autogenerated cols if needed     
          
           psql -d "$src_db" -c  \
           "copy ( SELECT col_1 , col2 FROM table_to_copy) TO STDOUT" |\
           psql -d "$tgt_db" -c "\copy table_to_copy (col_1 , col2) FROM STDIN"
          

          【讨论】:

            【解决方案11】:

            要在本地设置中将表从数据库 A 移动到数据库 B,请使用以下命令:

            pg_dump -h localhost -U owner-name -p 5432 -C -t table-name database1 | psql -U owner-name -h localhost -p 5432 database2
            

            【讨论】:

            • 我试过了。这不起作用,因为您只能给它第一个密码。
            • @max 你可以在运行命令之前执行export PGPASSWORD=<passw>
            【解决方案12】:

            如果两个 DB(from & to) 都受密码保护,在这种情况下终端不会询问两个 DB 的密码,密码提示只会出现一次。 因此,要解决此问题,请将密码与命令一起传递。

            PGPASSWORD=<password> pg_dump -h <hostIpAddress> -U <hostDbUserName> -t <hostTable> > <hostDatabase> | PGPASSWORD=<pwd> psql -h <toHostIpAddress> -d <toDatabase> -U <toDbUser>
            

            【讨论】:

              【解决方案13】:

              您可以执行以下操作:

              pg_dump -h <host ip address> -U <host db user name> -t <host table> > <host database> | psql -h localhost -d <local database> -U <local db user>
              

              【讨论】:

              • 你能不能说点什么
              • 那是合法的?你拥有我
              【解决方案14】:

              查看python script

              python db_copy_table.py "host=192.168.1.1 port=5432 user=admin password=admin dbname=mydb" "host=localhost port=5432 user=admin password=admin dbname=mydb" alarmrules -w "WHERE id=19" -v
              Source number of rows = 2
              INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister1',true,false);
              INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister2',true,false);
              

              【讨论】:

                【解决方案15】:

                这对我有用。 首先转储到文件:

                pg_dump -h localhost -U myuser -C -t my_table -d first_db>/tmp/table_dump
                

                然后加载转储文件:

                psql -U myuser -d second_db</tmp/table_dump
                

                【讨论】:

                • 对于转储负载也需要“-h localhost”
                【解决方案16】:

                user5542464Piyush S. Wanare 的回答相同,但分为两步:

                pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase > dump
                cat dump | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase
                

                否则管道会同时询问两个密码。

                【讨论】:

                • 我可以提及目标数据库的表名吗?
                【解决方案17】:

                如果你有两个远程服务器,那么你可以按照这个:

                pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase
                

                如果您已经有现有的模式,它将把提到的源数据库表复制到目标数据库的同名表中。

                【讨论】:

                  【解决方案18】:

                  我在这里尝试了一些解决方案,它们真的很有帮助。根据我的经验,最好的解决方案是使用 psql 命令行,但有时我不想使用 psql 命令行。所以这是 pgAdminIII

                  的另一种解决方案
                  create table table1 as(
                   select t1.* 
                   from dblink(
                     'dbname=dbSource user=user1 password=passwordUser1',
                     'select * from table1'  
                    ) as t1(
                      fieldName1 as bigserial,
                      fieldName2 as text,
                      fieldName3 as double precision 
                    )
                   )
                  

                  这种方法的问题是,你要复制的表的字段名和类型必须要写。

                  【讨论】:

                    【解决方案19】:

                    您必须使用 DbLink 将一个表数据复制到不同数据库的另一个表中。 您必须安装和配置 DbLink 扩展才能执行跨数据库查询。

                    我已经创建了关于这个主题的详细帖子。 Please visit this link

                    【讨论】:

                      【解决方案20】:

                      您还可以使用 pgAdmin II 中的备份功能。只需按照以下步骤操作:

                      • 在 pgAdmin 中,右键单击要移动的表,选择“备份”
                      • 选择输出文件的目录并将格式设置为“普通”
                      • 点击“Dump Options #1”选项卡,选中“Only data”或“only Schema”(取决于您在做什么)
                      • 在“查询”部分下,单击“使用列插入”和“用户插入命令”。
                      • 单击“备份”按钮。这将输出到 .backup 文件
                      • 使用记事本打开这个新文件。您将看到表/数据所需的插入脚本。将这些复制并粘贴到 pgAdmin 中的新数据库 sql 页面中。作为 pgScript 运行 - 查询->作为 pgScript F6 执行

                      效果很好,一次可以处理多个表。

                      【讨论】:

                      • 这是一个很好的基于 gui 的解决方案,用于在数据库之间移动数据。谢谢!
                      • 您可以在Objects 部分下选择多个表。在 OSX 上,单击 SQL 按钮或通过Tools 菜单获取SQL Editor 以粘贴从备份文件复制的 SQL。
                      • 有效,谢谢。虽然在大桌子上非常慢..有没有更好的方法来加快速度? (比如忽略外键什么的?)
                      • @Timothy 这是the postgres documentation page,了解如何加快备份和恢复速度
                      • 旧答案但仍然相关,效果很好,只是不要忘记在导出所有数据库时设置禁用触发器
                      【解决方案21】:

                      使用 pg_dump 转储表数据,然后使用 psql 恢复。

                      【讨论】:

                      • 然后使用另外一个databaserole连接,这个角色有足够的权限。 postgresql.org/docs/8.4/static/app-pgdump.html
                      • 我做错了什么? pg_dump -t "tablename" dbName --role "postgres" > db.sql "postgres" 将是我试图将角色设置为的用户。它仍然给我“访问被拒绝”。
                      • 你有权限写db.sql文件吗?
                      • 如何查看我有哪些权限?
                      • 不是一个真正有用的答案,因为其他答案向您展示了如何使用 pg_dump
                      猜你喜欢
                      • 1970-01-01
                      • 2023-02-15
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-09-16
                      • 2017-06-03
                      • 1970-01-01
                      相关资源
                      最近更新 更多