0

我正在尝试从表中隔离 toast 数据,以便可以在没有 toast 数据的情况下转储表。我知道必须有办法做到这一点,但我无法到达那里......建议将不胜感激

4

2 回答 2

1

使用查询选项尝试COPY(或 psql 的 \copy) - 您可以选择要导出的列。您还可以选择 CSV 格式而不是制表符分隔、空值的表示等。

于 2012-06-21T08:12:49.283 回答
0

TOAST是 PostgreSQL内部存储数据的方式。作为用户,对于您来说,只有您委托给数据库的值才能为您保留。

TOAST 主要用于文本数据,当元组的任何属性使元组的大小超过 8k 时(如果 PostgreSQL 使用默认页面大小编译)。这发生在数据库引擎内部,对用户透明。比如说,如果您要插入一行包含大约 10k 个符号的文本,则相应的属性将是 TOASTed。

鉴于 TOAST 的工作原理,您的问题看起来像:如何转储没有包含大块数据的属性的表?我似乎不清楚这样做的目的是什么,因为您的转储将不完整。


编辑:我不知道如何查找任何元组的任何属性是否具有 TOASTed 值。相反,我将消除所有可以具有TOASTed 值的属性。

以下查询将为您提供始终处于PLAIN存储模式的表的所有列:

SELECT a.attname
  FROM pg_class t
  JOIN pg_attribute a ON t.oid = a.attrelid
  JOIN pg_type typ ON typ.oid = a.atttypid
 WHERE t.relkind='r' AND t.relname = 'element'
   AND a.attnum > 0 AND NOT a.attisdropped
   AND typ.typstorage='p'
 ORDER BY a.attnum;

此查询将生成所需的SQL,您可以将其包装在脚本中或 PL/pgSQL 的EXECUTE语句中:

SELECT 'COPY '||quote_ident(t.relname)||
       '('||string_agg(a.attname, ',' ORDER BY a.attnum)||') TO stdout;'
  FROM pg_class t
  JOIN pg_attribute a ON t.oid = a.attrelid
  JOIN pg_type typ ON typ.oid = a.atttypid
 WHERE t.relkind='r' AND t.relname = '<YOUR_TABLE>'
   AND a.attnum > 0 AND NOT a.attisdropped
   AND typ.typstorage='p'
 GROUP BY t.relname;
于 2012-06-21T09:04:17.487 回答