如何将MySQLdb&#39的fetchall()的输出转换为文件流?

时间:2016-02-13 09:25:49

标签: python filestream mysql-python gnupg

我正在编写一个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(),而无需将临时文件写入未加密的磁盘?可能有数百万行数据。因此,立即将其全部读入内存并不是一个可行的解决方案。

1 个答案:

答案 0 :(得分:0)

您可以使用与io module中的io.StringIOio.BytesIO类似的类似文件的对象。

查看最新的source code,不再有encrypt_file,而是encrypt wraps the data in a binary stream使用StringIO or BytesIO depending on the Python Version

因此,没有什么能阻止您直接使用encrypt,如果您想要更好地控制数据的加密方式,您可以实现虚拟文件对象,或者只是将数据写入io.BytesIO对象。