从pg_dump输出中删除注释

13

执行 PostgreSQL 的 pg_dump 时,对于每个元素都会插入一些注释,具体如下。

--
-- Name: my_table; Type: TABLE; Schema: account; Owner: user; Tablespace:
--

CREATE TABLE my_table(
    id integer
);

--
-- Name: my_seq; Type: SEQUENCE; Schema: account; Owner: user
--

CREATE SEQUENCE my_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

有没有可能强制pg_dump删除(排除)它们?我只想得到:

CREATE TABLE my_table(
    id integer
);

CREATE SEQUENCE my_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

2
将其通过 sed 管道处理,如下所示:sed -e '/^--/d' - Laurenz Albe
1
@LaurenzAlbe,您能否发表一篇最好描述您建议的答案?我不明白如何使用它。 - Marcio Mazzucato
你使用的是什么操作系统? - Laurenz Albe
2
@vitaly-t,在我的使用情况下,它们变得很明显,文件大小也增加了很多。 - Marcio Mazzucato
@MarcioMazzucato 谢谢,我非常怀疑这一点。我在下面添加了自己的答案,值得一提的是,它比之前的答案更好地减小了文件大小,因为它可以完全压缩SQL,删除所有冗余空格。 - vitaly-t
显示剩余2条评论
4个回答

19
在UNIX类型的操作系统中,我会像这样做:
pg_dump [options] mydatabase | sed -e '/^--/d' >mydatabase.dmp

这可能会意外地吞噬以--开头的数据行。为了解决这个问题,使用pg_dump命令的--inserts选项。


2
这将删除该行而不会留下空行。您在原始转储文件中看到的空行本来就是空的。使用sed命令/^$/d来删除它们。 - Laurenz Albe
2
请注意,使用默认的 pg_dump 输出格式,如果您的任何表包含以 -- 开头的行内容,那么您将删除该数据!(例如:CREATE TABLE strs(s text); INSERT INTO strs(s) VALUES('-- hi');。) - wchargin
1
@wchargin 那不是真的。试试看。 - Laurenz Albe
2
@LaurenzAlbe:当然可以使用psql恢复以“--”开头的值。显式删除带有sed的行的代码来自您对此问题的回答。我的评论指出,您提供的sed -e '/^--/d'旨在仅删除由pg_dump生成的SQL注释,但实际上也可能会删除转储中的实际数据。 - wchargin
1
@wchargin 哦,现在我明白了。你是对的,那是我回答中的一个缺陷。你可以使用 pg_dump--inserts 选项来解决它。 - Laurenz Albe
显示剩余3条评论

9
我刚刚提交了这个补丁,适用于Postgres 11+(仍在考虑中),它应该允许无注释地转储,这应该比我们使用的其他方法略好一些,直到找到理想的解决方案为止。
如果有足够的声音,它甚至可能被回溯到Postgres 10!

[更新]

这现在是Postgres v11+的一个功能。

pg_dump --no-comments

2
一个长期以来备受期待的功能!:-D - akahunahi
这是否已经升级到11版本?我没有看到有记录。 - xenoterracide
实际上,它确实在2018年1月份发生了——https://www.thatguyfromdelhi.com/2017/05/patch-using-no-comments-with-pgdump.html?m=1 - Robins Tharakan
用法:pg_dump --no-comments - Gajus
3
使用pg_dump(PostgreSQL)11.11(Debian 11.11-1.pgdg90+1),--no-comments标志存在,但似乎实际上并没有起作用。至少在我使用的标志组合中是这样。 - jberryman
16
作者希望从pg_dump输出中删除以"--"开头的行,而不是禁用SQL COMMENT语句的输出。 - fjf2002

2
只有两个好的理由可以从SQL中删除注释:
  1. SQL文件包含需要动态替换的格式化变量(占位符)。在这种情况下,删除注释可防止在注释中引用这些变量时出现假变量检测。
  2. SQL文件要被最小化,以减少需要通过IO进入数据库服务器的内容大小。
在任一情况下,都意味着SQL文件现在仅用于执行,而不是用于阅读。
特别是对于PostgreSQL,有一个名为pg-minify的软件包可以实现这一点:
  • 它会删除所有注释并最小化生成的SQL
  • 它可以选择将SQL压缩到其最小限度(选项compress
完整示例
const minify = require('pg-minify');
const fs = require('fs');

fs.readFile('./sqlTest.sql', 'utf8', (err, data) => {
    if (err) {
        console.log(err);
    } else {
        console.log(minify(data));
    }
});

2
好建议!但由于它依赖于NodeJS,我今天不能使用它。@Laurenz Albe的解决方案很适合我的情况,因为它更灵活,我可以使用本地的PostgreSQL和Linux命令。 - Marcio Mazzucato
2
pg_dump 的输出中删除注释的第三个好理由是:它们占用了大量垂直空间(每个注释占用六行,只有一行有文本),使得阅读变得更加困难,并且没有传达任何信息。例如,“Name: mytable; Type: TABLE; Schema: public” 这样的行注释在紧接着的 CREATE TABLE public.mytable 之后就变得毫无意义。我想要删除这些注释,以使其更易于人类阅读,而不是为了缩小它。 - wchargin
删除注释可以使模式转储在不同平台之间保持一致,这对于将其提交到版本控制是必要的。 - Ilya Semenov

1

Marcio,管道是将一个进程的输出直接馈送到另一个进程以达到特定目的的过程。假设您正在使用Julia来实现所需的结果。创建一个测试数据库并进行操作,以确保获得所需的结果。这个Julia命令会生成带有注释的备份:

run(pipeline(`pg_dump -d test`,"testdump.sql"))

这里要求Julia将备份倒入testdump.sql中以便我们检查结果。注意反引号。接下来是另一个命令,使用了@LaurenzAlbe建议的过滤器:

run(pipeline(`cat testdump.sql`,`sed -e '/^--/d'`,"testdump2.sql"))

这里有一个三部分管道,它扫描带有注释的备份,剥离注释并将剩余内容倾倒到testdump2中。现在您可以检查第一个和第二个文件是否符合要求。
一旦您对@LaurenzAlbe提供的解决方案有信心,您可以进行所需的替换,以便在一个管道命令中运行整个过程。当然,您也可以直接在bash终端、Python或您选择的脚本引擎中执行相同的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接