我正在编写一个python方法来转储MySQL表的全部内容。但是,此表包含个人身份信息(PII)。我要求此数据必须经过GPG加密。此外,要求是不允许以未加密的形式将这些数据写入磁盘(即使这只是稍后删除的临时文件)
我通过使用subprocess.Popen()
并将mysql
可执行文件的输出直接传递给gpg
可执行文件然后将该输出传递给stdout来暂时解决了这个问题:
p1 = subprocess.Popen(
'mysql -h127.0.0.1 -Dmydbinstance -umyuser -pmyPassword -e "select * from my_table"',
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
p2 = subprocess.Popen(
"gpg --encrypt -r myemail@gmail.com",
stdin=p1.stdout,
stdout=subprocess.PIPE
)
p1.stdout.close()
print p2.communicate()[0]
它有效,但在我看来,这似乎是一个可怕的黑客。 fork shell进程执行此操作感觉非常错误。
所以我想在python中本地执行此操作(不使用popen()
)。我有一个MySQLdb连接到数据库。 python-gnupg
模块可以对文件流进行加密。但是如何将MySQLdb的fetchall()输出转换为文件流?到目前为止,我只有这个:
import MySQLdb
import gpg
DBConn = MySQLdb.Connect(host='127.0.0.1', user='myuser', passwd='myPassword', db='mydbinstance', port=3306, charset='utf8')
DBConn.autocommit(True)
cur = DBConn.cursor(MySQLdb.cursors.DictCursor)
cur.execute("select * from my_table")
if cur.rowcount >= 1:
rows = cur.fetchall()
else
rows = []
for i in rows:
print i
# WHAT DO I NEED TO DO HERE TO TURN THE DB OUTPUT INTO A FILE STREAM?
encrypted_ascii_data = gpg.encrypt_file(stream, recipient_fingerprint)
如何将fetchall()的输出转换为文件流,以便我可以将其发送到gpg.encrypt_file()
,而无需将临时文件写入未加密的磁盘?可能有数百万行数据。因此,立即将其全部读入内存并不是一个可行的解决方案。
答案 0 :(得分:0)
您可以使用与io module中的io.StringIO
或io.BytesIO
类似的类似文件的对象。
查看最新的source code,不再有encrypt_file
,而是encrypt
wraps the data in a binary stream使用StringIO or BytesIO depending on the Python Version
因此,没有什么能阻止您直接使用encrypt
,如果您想要更好地控制数据的加密方式,您可以实现虚拟文件对象,或者只是将数据写入io.BytesIO
对象。