【问题标题】:Storing and retrieving zip files in SQLite gives "Could not decode to UTF-8"在 SQLite 中存储和检索 zip 文件会导致“无法解码为 UTF-8”
【发布时间】:2021-03-15 05:22:05
【问题描述】:

我在 SQLite 3 中有一个如下表,我打算用它来存储各种文件:txt、pdf、图像和 zip 文件。

CREATE TABLE zip (filename TEXT PRIMARYKEY NOT NULL, zipfile BLOB NOT NULL);

为了存储和检索,我正在尝试以下 python 代码

#!env/bin/python


import sqlite3 as lite
import os
import sys

def insertfile(_filename):
    try:
        con = lite.connect('histogram.db', detect_types=lite.PARSE_DECLTYPES)
        con.row_factory = lite.Row
        cur = con.cursor()
        cur.execute('PRAGMA foreign_keys=ON;')
        _f = open(_filename,'rb')
        _split = os.path.split(_filename)
        _file = _split[1]
        _blob = _f.read()
        cur.execute('INSERT INTO zip (filename,zipfile) VALUES (?,?)', (_file,lite.Binary(_blob)))
        _f.close()
        con.commit()
        cur.close()
        con.close()
    except Exception as ex:
        print ex

def getfile(_filename):
    try:
        con = lite.connect('histogram.db', detect_types=lite.PARSE_DECLTYPES)
        con.row_factory = lite.Row
        cur = con.cursor()
        cur.execute('PRAGMA foreign_keys=ON;')
        cur.execute('SELECT zipfile from zip where filename = ?', (_filename,))
        _files = cur.fetchall()
        if len(_files) > 0:
            _file  = open('Test/'+ _filename,'wb')
            _file.write(_files[0]['zipfile'])
            _file.close()
        cur.close()
        con.close()
    except Exception as ex:
        print ex

if __name__ == '__main__':
    print 'works'
    insertfile(sys.argv[1])
    getfile(os.path.split(sys.argv[1])[1])

当我对 .txt.py.pdf 等文件进行测试时,它工作正常。

使用 Zip 文件,在存储到表时不会出错,但在检索文件时会出错:

无法解码为带有文本“PK”的 UTF-8 列“zipfile”

似乎有一些编码或解码问题。

【问题讨论】:

  • python 本身不支持这些文件类型。如果您尝试在记事本中打开这些文件类型,您会发现它们是随机的简介
  • 谢谢 - 但我只是想存储文件的字节 - 使用 'rb' 和 'wb' 选项打开以将文件存储为二进制数据。我已经能够通过使用 lite.Binary(_blob) 存储文件来解决 pdf、png 等问题。 zip 文件在检索时仍然给我带来问题
  • 能否粘贴完整的跟踪信息?
  • @Daniel 代码现在可以工作了。不确定如何纠正 zip 文件问题。只是为了尝试,我注释掉了插入,然后运行了检索,它起作用了。现在,当我取消注释插入时,程序可以正常工作。不知道为什么之前的 zip 文件会出错。
  • 难道detect_types=lite.PARSE_DECLTYPES 尝试将您的字节块转换为 UTF-8 字符串,但失败了,因为它不是有效的 UTF-8 字符串?我会删除它并重试。

标签: python sqlite unicode-string


【解决方案1】:

我基本上尝试使用其中一个问题的代码

Insert binary file in SQLite database with Python .

它最初适用于 pdf、png、jpg 文件。但我仍然收到 Zip 文件的错误。当我注释掉插入并运行检索代码时,它起作用了。现在下面的代码可以工作了。

def insertfile(_filename):
    try:
        con = lite.connect('histogram.db', detect_types=lite.PARSE_DECLTYPES)
        con.row_factory = lite.Row
        cur = con.cursor()
        cur.execute('PRAGMA foreign_keys=ON;')
        _f = open(_filename,'rb')
        _split = os.path.split(_filename)
        _file = _split[1]
        _blob = _f.read()
        cur.execute('INSERT INTO zip (filename,zipfile) VALUES (?,?)', (_file,lite.Binary(_blob)))
        _f.close()
        con.commit()
        cur.close()
        con.close()
    except Exception as ex:
        print ex

def getfile(_filename):
    try:
        con = lite.connect('histogram.db', detect_types=lite.PARSE_DECLTYPES)
        con.row_factory = lite.Row
        cur = con.cursor()
        cur.execute('PRAGMA foreign_keys=ON;')
        cur.execute('SELECT zipfile from zip where filename = ?', (_filename,))
        _files = cur.fetchall()
        if len(_files) > 0:
            _file  = open('Downloads/'+ _filename,'wb')
            _file.write(_files[0]['zipfile'])
            _file.close()
        cur.close()
        con.close()
    except Exception as ex:
        print ex

if __name__ == '__main__':
    print 'works'
    insertfile(sys.argv[1])
    getfile(os.path.split(sys.argv[1])[1])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 2013-03-12
    • 2015-07-19
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多