将PostgreSQL表中的特定行导出为INSERT SQL脚本

nul*_*ull 171 postgresql export insert sql-scripts postgresql-copy

我有一个名为的数据库模式:nyummy和一个名为的表cimory:

create table nyummy.cimory (
  id numeric(10,0) not null,
  name character varying(60) not null,
  city character varying(50) not null,
  CONSTRAINT cimory_pkey PRIMARY KEY (id)
);
Run Code Online (Sandbox Code Playgroud)

我想将cimory表的数据导出为插入SQL脚本文件.但是,我只想导出城市等于'东京'的记录/数据(假设城市数据都是小写的).

怎么做?

解决方案是否在免费的GUI工具或命令行中无关紧要(尽管GUI工具解决方案更好).我曾尝试过pgAdmin III,但我找不到这样做的选择.

Clo*_*eto 257

使用要导出的集创建表,然后使用命令行实用程序pg_dump导出到文件:

create table export_table as 
select id, name, city
from nyummy.cimory
where city = 'tokyo'
Run Code Online (Sandbox Code Playgroud)
$ pg_dump --table=export_table --data-only --column-inserts my_database > data.sql
Run Code Online (Sandbox Code Playgroud)

--column-inserts 将转储为具有列名称的insert命令.

--data-only 不要转储架构.

如下所述,无论何时需要新的导出,创建视图而不是表都将避免创建表.

  • 好的,到目前为止您的解决方案仍然有效 遗漏的一件事是我需要添加"-U user_name".我也几乎成功使用ToraSQL工具,只是它在脚本结果中的日期时间数据中有错误.如果没有人能在2天内提供GUI工具解决方案,那么您的答案将被接受 (3认同)
  • 只想分享给其他人,你也可以使用这个免费的GUI工具:SQL Workbench/J(用postgreSQL jdbc4驱动程序),做同样的事情. (2认同)
  • 使用`create view export_view...` 会好得多,因为视图会随着基表的变化而保持最新。[docs](https://www.postgresql.org/docs/9.5/static/app-pgdump.html) 说`--table=table: Dump only tables (or **views**...` 所以我有一些希望这会奏效,但遗憾的是转储视图不会产生任何数据。:P (2认同)

Erw*_*ter 164

仅供数据导出使用COPY.
你得到一个文件,每行一个表行作为纯文本(而不是INSERT命令),它更小更快:

COPY (SELECT * FROM nyummy.cimory WHERE city = 'tokio') TO '/path/to/file.csv';
Run Code Online (Sandbox Code Playgroud)

使用以下内容将相同结构导入同一结构的另一个表:

COPY other_tbl FROM '/path/to/file.csv';
Run Code Online (Sandbox Code Playgroud)

COPY写入和读取服务器本地的文件,不像客户端程序那样,pg_dump或者psql读取和写入客户端本地文件.如果两者都在同一台机器上运行,那么它并不重要,但它适用于远程连接.

还有\copypsql命令:

执行前端(客户端)副本.这是一个运行SQL COPY命令的操作,但不是服务器读取或写入指定的文件,psql读取或写入文件并在服务器和本地文件系统之间路由数据.这意味着文件可访问性和权限是本地用户的权限,而不是服务器的权限,并且不需要SQL超级用户权限.

  • OP专门为_data调用insert sql脚本file_.我猜他说的是'插入'命令,不是吗? (8认同)
  • 比接受的解决方案容易得多. (5认同)
  • `STDIN`和`STDOUT`可用于代替文件路径,对小数据导出很有用. (3认同)
  • @Clodoaldo:你可能是对的,在这种情况下你的答案会更合适。人们还可以单独复制 pgAdmin 中的 CREATE 脚本(正如 OP 提到的 GUI 一样)。 (2认同)
  • 如果没有 `--column-inserts` 标志,pg_dump 会对它生成的 SQL 代码中的每个表使用来自 STDIN 的 `COPY`。 (2认同)
  • 请注意,SELECT列的顺序与目标数据库中列的顺序相匹配.如果没有,这可能会失败,或者更糟糕的是,成功但插入不良数据. (2认同)

And*_*i R 25

这是一种使用pgAdmin手动将表导出到脚本而不需要额外安装简单快捷的方法:

  1. 右键单击目标表并选择"备份".
  2. 选择存储备份的文件路径.格式选择"普通".
  3. 打开底部的"转储选项#2"选项卡,然后选中"使用列插入".
  4. 单击备份按钮.
  5. 如果使用文本阅读器(例如notepad ++)打开生成的文件,则会获得一个脚本来创建整个表.从那里你可以简单地复制生成的INSERT语句.

这个方法也适用于制作export_table的技术,如@Clodoaldo Neto的回答所示.

在目标表上单击右键,然后选择

选择目标路径并将格式更改为

打开底部的

您可以从那里复制INSERT语句.


mac*_*ery 9

SQL Workbench具有这样的功能.

运行查询后,右键单击查询结果并选择"将数据复制为SQL> SQL插入"


M.V*_*lee 6

对于我的用例,我能够简单地管道grep.

pg_dump -U user_name --data-only --column-inserts -t nyummy.cimory | grep "tokyo" > tokyo.sql
Run Code Online (Sandbox Code Playgroud)

  • 必须考虑在其他领域拥有'东京'. (2认同)

小智 6

我试图根据@PhilHibbs 代码以不同的方式编写一个程序。请看一看并测试。

 CREATE OR REPLACE FUNCTION dump(IN p_schema text, IN p_table text, IN p_where text)
   RETURNS setof text AS
 $BODY$
 DECLARE
     dumpquery_0 text;
     dumpquery_1 text;
     selquery text;
     selvalue text;
     valrec record;
     colrec record;
 BEGIN

     -- ------ --
     -- GLOBAL --
     --   build base INSERT
     --   build SELECT array[ ... ]
     dumpquery_0 := 'INSERT INTO ' ||  quote_ident(p_schema) || '.' || quote_ident(p_table) || '(';
     selquery    := 'SELECT array[';

     <<label0>>
     FOR colrec IN SELECT table_schema, table_name, column_name, data_type
                   FROM information_schema.columns
                   WHERE table_name = p_table and table_schema = p_schema
                   ORDER BY ordinal_position
     LOOP
         dumpquery_0 := dumpquery_0 || quote_ident(colrec.column_name) || ',';
         selquery    := selquery    || 'CAST(' || quote_ident(colrec.column_name) || ' AS TEXT),';
     END LOOP label0;

     dumpquery_0 := substring(dumpquery_0 ,1,length(dumpquery_0)-1) || ')';
     dumpquery_0 := dumpquery_0 || ' VALUES (';
     selquery    := substring(selquery    ,1,length(selquery)-1)    || '] AS MYARRAY';
     selquery    := selquery    || ' FROM ' ||quote_ident(p_schema)||'.'||quote_ident(p_table);
     selquery    := selquery    || ' WHERE '||p_where;
     -- GLOBAL --
     -- ------ --

     -- ----------- --
     -- SELECT LOOP --
     --   execute SELECT built and loop on each row
     <<label1>>
     FOR valrec IN  EXECUTE  selquery
     LOOP
         dumpquery_1 := '';
         IF not found THEN
             EXIT ;
         END IF;

         -- ----------- --
         -- LOOP ARRAY (EACH FIELDS) --
         <<label2>>
         FOREACH selvalue in ARRAY valrec.MYARRAY
         LOOP
             IF selvalue IS NULL
             THEN selvalue := 'NULL';
             ELSE selvalue := quote_literal(selvalue);
             END IF;
             dumpquery_1 := dumpquery_1 || selvalue || ',';
         END LOOP label2;
         dumpquery_1 := substring(dumpquery_1 ,1,length(dumpquery_1)-1) || ');';
         -- LOOP ARRAY (EACH FIELD) --
         -- ----------- --

         -- debug: RETURN NEXT dumpquery_0 || dumpquery_1 || ' --' || selquery;
         -- debug: RETURN NEXT selquery;
         RETURN NEXT dumpquery_0 || dumpquery_1;

     END LOOP label1 ;
     -- SELECT LOOP --
     -- ----------- --

 RETURN ;
 END
 $BODY$
   LANGUAGE plpgsql VOLATILE;
Run Code Online (Sandbox Code Playgroud)

进而 :

-- for a range
SELECT dump('public', 'my_table','my_id between 123456 and 123459'); 
-- for the entire table
SELECT dump('public', 'my_table','true');
Run Code Online (Sandbox Code Playgroud)

在我的 postgres 9.1 上测试,使用混合字段数据类型(文本、双精度、整数、无时区的时间戳等)的表。

这就是为什么需要 TEXT 类型的 CAST。我的测试正确运行了大约 900 万行,看起来它在运行 18 分钟之前就失败了。

ps:我在WEB上找到了mysql的等价物。


Gio*_*ili 5

您可以使用特定记录查看表,然后转储 sql 文件

CREATE VIEW foo AS
SELECT id,name,city FROM nyummy.cimory WHERE city = 'tokyo'
Run Code Online (Sandbox Code Playgroud)

  • 我在pgAdmin III中尝试过,但是对于View对象,没有转储的选项。 (3认同)