我会使用直接支持 PostgreSQL 的脚本语言。
regress
给定一个名为的数据库,该数据库包含一个名为files
列fileid
(一个整数)和filedata
(一个字节)的表,这可以很好地完成这项工作。它将数据写入由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 的脚本语言。
如果您不需要它,交易安全会更容易一些;只需在一次调用中获取 ID psql
,然后在后续调用中获取文件数据。它会更慢并且不会是交易安全的,但它会更容易。