
使用 couchdb-python 库向 couchdb 文档添加二进制附件(如 png 图片)时,必须传入文件对象而非文件路径字符串,否则会将路径名本身作为内容写入,导致附件损坏、长度错误及浏览器无法渲染。
使用 couchdb-python 库向 couchdb 文档添加二进制附件(如 png 图片)时,必须传入文件对象而非文件路径字符串,否则会将路径名本身作为内容写入,导致附件损坏、长度错误及浏览器无法渲染。
在 CouchDB 中,附件是文档的一部分,需以原始二进制形式上传,并正确声明 content_type。常见误区是误将文件路径字符串(如 'Scan.png')直接作为 content 参数传入 put_attachment(),这会导致库将字符串 "Scan.png"(共 8 字节)当作附件内容写入,而非其实际图像数据——因此 Futon 显示 “Cannot be displayed because it contains an error”,且 _attachments 中 length 显示为 8,与真实大小(如 199281 字节)严重不符。
✅ 正确做法是:以二进制只读模式('rb')打开文件,并传入文件对象:
import couchdb
couch = couchdb.Server('http://a73657.berlin.de:5984')
db = couch['vl']
doc_id = "test_file"
doc = db.get(doc_id)
# ✅ 正确:传入 file object(二进制模式)
with open('Scan.png', 'rb') as f:
db.put_attachment(doc, f, filename='Scan.png', content_type='image/png')⚠️ 注意事项:
安全 Python 代码沙箱:在隔离的沙箱中执行任意 Python 代码,预装 requests、NumPy、pandas 库。返回 stdout、stderr。
- content_type 不应包含 ;base64 —— put_attachment() 默认处理原始二进制流;添加 ;base64 会被 CouchDB 当作普通 MIME 类型解析,可能导致服务端解码异常或客户端渲染失败;
- 建议使用 with open(...) as f: 确保文件句柄安全关闭;
- 若需上传内存中字节数据(如从网络响应获取),可使用 io.BytesIO(b'...') 构造文件类对象;
- 上传后务必调用 db.save(doc)(或确保 doc 已被更新并提交),因为 put_attachment() 会修改 doc['_rev'],但不会自动保存变更到数据库(couchdb-python v1.x 中 put_attachment 默认不自动 save,需显式保存)。
? 补充说明:put_attachment() 的参数顺序为
db.put_attachment(doc, content, filename, content_type=None),其中 content 必须是 bytes 或支持 read() 的文件类对象。字符串将被按字节长度直接写入,绝非读取文件内容。
立即学习“Python免费学习笔记(深入)”;
通过以上修正,附件将正确存储,Futon 或 HTTP API 查询返回的 _attachments 中 length 和 digest 将与源文件一致,图片也可正常预览。

















