【问题标题】:Removing comments from pg_dump output从 pg_dump 输出中删除注释
【发布时间】:2017-01-30 17:07:36
【问题描述】:

当 PostgreSQL pg_dump 完成后,它会为每个元素插入一些 cmets,如下所示。

--
-- 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;

【问题讨论】:

  • 像这样通过sed 管道:sed -e '/^--/d'
  • @LaurenzAlbe,您能否发布一个最能描述您的建议的答案?我不明白如何使用它。
  • 你使用的是什么操作系统?
  • @LaurenzAlbe,我正在使用 CentOS 7.2 和 PostgreSQL 9.2.5
  • @vitaly-t,在我的用例中,它们变得很明显并且文件大小增加了很多

标签: sql postgresql postgresql-9.2


【解决方案1】:

在 UNIX 类型的操作系统上,我会这样做:

pg_dump [options] mydatabase | sed -e '/^--/d' >mydatabase.dmp

这可能会意外吞下以-- 开头的数据行。要解决该问题,请使用pg_dump--inserts 选项。

【讨论】:

  • 它工作正常,非常感谢!它将 cmets 替换为空行,是否可以将其删除?不是很重要,但文件会更干净。
  • 这将删除该行并且留下一个空行。您看到的空行在原始转储文件中是空的。使用sed 命令/^$/d 删除这些。
  • 请注意,使用默认的pg_dump 输出格式,如果您的任何表包含内容以-- 开头的行,您将删除该数据! (例如:CREATE TABLE strs(s text); INSERT INTO strs(s) VALUES('-- hi');。)
  • @wchargin 这不是真的。试试看。
  • @LaurenzAlbe:是的,当然psql 可以恢复以-- 开头的值。明确删除sed 行的代码来自您对此问题的回答。我的评论是指出您的答案提供的sed -e '/^--/d'意图仅删除pg_dump生成的SQL cmets,也可以从转储中删除实际数据。
【解决方案2】:

我刚刚为 Postgres 11+(仍在考虑中)提交了这个 patch,它应该允许一个人在没有评论的情况下转储(直到一个理想的解决方案到位),这应该是一个稍微比我们使用的那些更好。

如果有足够多的声音,它甚至可能会被修补到 Postgres 10!


[更新]

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

【讨论】:

  • 要求已久的功能! :-D
  • 这个到 11 了吗?我没有看到它记录在案
  • 事实上,早在 2018 年 1 月 - thatguyfromdelhi.com/2017/05/…
  • 用法:pg_dump --no-comments
  • 作者想从 pg_dump 输出中删除以 -- 开头的行,而不是禁用 SQL COMMENT 语句的输出。
【解决方案3】:

从 SQL 中删除 cmets 只有两个很好的理由:

  1. SQL 文件包含需要动态替换的格式化变量(占位符)。在这种情况下,删除 cmets 可以防止在 cmets 中引用这些变量时进行错误的变量检测。

  2. SQL 文件将被最小化,以减少需要通过 IO 进入数据库服务器的大小。

在任何一种情况下,这都意味着 SQL 文件现在仅用于执行,而不是用于读取。

特别是对于 PostgreSQL,有一个包 pg-minify 正是这样做的:

  • 它会删除所有 cmets 并最小化生成的 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));
    }
});

【讨论】:

  • 好建议!但由于它依赖于 NodeJS,我今天不能使用它。 @Laurenz Albe 的解决方案非常适合我的情况,因为它更灵活,我可以使用原生 PostgreSQL 和 Linux 命令。
  • pg_dump 的输出中删除 cmets 有第三个很好的理由:它们占用了一堆垂直空间(每行六行,其中只有一行有文本)并且不传达任何信息。行注释“名称:mytable;类型:TABLE;架构:公共”如果紧跟在CREATE TABLE public.mytable 后面,则它是无用的。我想专门删除这些 cmets 以使其人类可读,而不是缩小它。
【解决方案4】:

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

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

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

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

这里我们有一个由三部分组成的管道,它使用 cmets 扫描备份,剥离 cmets 并将剩余的内容转储到 testdump2 中。您现在可以检查第一个和第二个文件是否是必需的。

一旦您确信@LaurenzAlbe 提供的解决方案是正确的,您就可以进行必要的替换以在一个管道命令中运行整个事情。当然,您可以直接在 bash 终端或 Python 或您选择的脚本引擎中执行相同的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-28
    • 2012-03-17
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 2015-05-11
    相关资源
    最近更新 更多