有将全文字段导入/导出为文件的简单方法?
主要问题出在export,这就是本页的标题。
PS:往返过程中的“同文件证明”——导入、导出回来并与原始文件比较——可以通过以下方式获得sha1sum
示范;请参阅下面的示例。因此,一个自然的需求也是通过 SQL 检查相同的 SHA1,避免在简单的检查任务上导出。
所有示例
导入全文进入全表(不是我需要的),
并测试可以导出为相同 text.
PS:我需要将一个文件导入到一个字段和一行中。
转换将整个表放入一个文件中(不是我需要的)
并测试可以导出相同 text.
PS:我需要将一行(一个字段)放入一个文件中。
通过SQL计算hash,字段的 SHA1.
Must be the same比较时...否则这对我来说不是一个解决方案。
以下示例显示了每个问题和一个不太优雅的解决方法。
1. 进口
CREATE TABLE ttmp (x text);
COPY ttmp FROM '/tmp/test.xml' ( FORMAT text ); -- breaking lines lines
COPY (SELECT x FROM ttmp) TO '/tmp/test_back.xml' (format TEXT);
检查原件和“背面”的内容是否完全相同:
sha1sum /tmp/test*.*
570b13fb01d38e04ebf7ac1f73dfad0e1d02b027 /tmp/test_back.xml
570b13fb01d38e04ebf7ac1f73dfad0e1d02b027 /tmp/test.xml
PS:看起来很完美,但这里的问题是使用了很多行。真正的导入解决方案可以将文件导入一行(和一个字段)。真正的导出解决方案是一个 SQL 函数,它生成test_back.xml
来自(单个字段的)单行。
2. 将全表转换为一个文件
用它来存储 XML:
CREATE TABLE xtmp (x xml);
INSERT INTO xtmp (x)
SELECT array_to_string(array_agg(x),E'\n')::xml FROM ttmp
;
COPY (select x::text from xtmp) TO '/tmp/test_back2-bad.xml' ( FORMAT text );
...但不起作用,因为我们可以检查sha1sum /tmp/test*.xml
, 不会产生相同的结果 for test_back2-bad.xml
.
所以也翻译一下\n
到 chr(10),使用外部工具(perl、sed 或任何其他)
perl -p -e 's/\\n/\n/g' /tmp/test_back2-bad.xml > /tmp/test_back2-good.xml
Ok, now test_back2-good.xml
具有与原始相同的哈希值(在我的示例中为“570b13fb ...”)。
使用 Perl 是一种解决方法,没有它怎么办?
3. 字段的SHA1
SELECT encode(digest(x::text::bytea, 'sha1'), 'hex') FROM xtmp;
未解决,与原始哈希值不一样(我的示例中的“570b13fb ...”)...也许::text
强制内部代表\n
符号,因此解决方案将直接转换为bytea
,但这是一个无效的强制转换。其他解决方法也不是解决方案,
SELECT encode(digest( replace(x::text,'\n',E'\n')::bytea, 'sha1' ), 'hex')
FROM xtmp
...我尝试CREATE TABLE btmp (x bytea)
and COPY btmp FROM '/tmp/test.xml' ( FORMAT binary )
,但出现错误(“未知的复制文件签名”)。