使用postgresql 8.4中的COPY命令导出bytea类型的数据,这对于单个记录可以正常工作:
copy (SELECT encode(test_column, 'hex') FROM test_table LIMIT 1) TO '/home/user/file.hex'
之后,我使用xxd
命令获取适当的文件类型。
如果这是一个非常菜鸟问题,请提前抱歉,但是可以将所有记录导出到file-1,file-2 ... file-n吗?什么是正确的语法或脚本?我似乎无法在postgresql副本中找到它。
例如,这是单行的bash脚本:
#!/bin/bash
psql \
-P t \
-P format=unaligned \
-X \
-U myuser \
-h myhost \
-c "select my_bytea_col from my_table where id=1" \
mydb \
| xxd -r -p > dump.txt
然而,我需要在所有ID上执行它并将它们保存在不同的文件下,例如file1.txt,file2.txt,file3.txt ..等等。
也可能非常有趣的是能够使用另一列的数据(例如id)来相应地命名生成的hex文件。
答案 0 :(得分:3)
我使用的脚本语言直接支持PostgreSQL。
这给了一个名为regress
的数据库非常好的工作,该数据库包含一个名为files
的表,列fileid
(整数)和filedata
(bytea)。它将数据写入outdir
变量指定的目录中的文件,在根据{filenameprefix}{fileid}{filenamesuffix}
之类的模式命名的文件中。
#!/usr/bin/env python3
import os
import sys
import psycopg2
outdir = "files"
filenameprefix = "f"
filenamesuffix = ""
def main():
os.makedirs(outdir, exist_ok=True)
conn = psycopg2.connect("dbname=regress")
curs = conn.cursor();
curs.execute("SELECT fileid, filedata FROM files;")
for (fileid, filedata) in curs:
fn = filenameprefix+str(fileid)+filenamesuffix
f = open(os.path.join(outdir, fn), "wb")
f.write(filedata)
f.close()
conn.close();
if __name__ == '__main__':
main()
我使用此代码创建上述脚本中引用的测试环境:
#!/usr/bin/env python3
import psycopg2
conn = psycopg2.connect("dbname=regress")
curs = conn.cursor()
curs.execute('CREATE TABLE files(fileid serial primary key, filedata bytea);')
for i in range(1,10)
curs.execute('INSERT INTO files(filedata) VALUES (%s);', (psycopg2.Binary(open('/dev/urandom','rb').read(1024)),))
编辑:为了使它与您在问题中使用的命名相同,我刚才假设是通用的匿名名称,请更改:
regress
- >无论您的数据库名称是什么files
- > my_table
fileid
- > id
filedata
- > my_bytea_col
这个脚本的等价物可以在bash中完成,这很麻烦。您需要使用协同进程以事务安全的方式执行此操作。您需要创建一个psql
协同进程并在其中打开SERIALIZABLE
事务,然后在SELECT fileid FROM files
中打开一个shell变量。将shell变量和每个ID SELECT filedata FROM files
循环到xxd
管道中,转到使用ID上的字符串插值创建的文件名。
IMO:不值得麻烦,使用一种脚本语言,为您提供直接的PostgreSQL访问。
如果您不需要交易安全,那就更容易了;只需在一个psql
调用中获取ID,然后在后续文件中获取文件数据。它会更慢,不会对交易安全,但它会更容易。