Pymongo GridFS 放置类型/属性错误

Posted

技术标签:

【中文标题】Pymongo GridFS 放置类型/属性错误【英文标题】:Pymongo GridFS put Type/Attribute errors 【发布时间】:2018-06-30 08:02:57 【问题描述】:

Put 操作在与MongoClientGridFS 一起使用时导致TypeAttribute 错误。然而,同样的操作通过mongofilesutility.Appreciate 指针传递。

版本信息

[xxxx@yyyy ~]$ python
Python 3.5.1 (default, Jan 20 2018, 19:04:00)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-18)] on linux
Type "help", "copyright", "credits" or "license" for more information.


[xxxx@yyyy ~]$ mongo
MongoDB shell version v3.6.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.1

>>> pymongo.version
'3.6.0'

代码

>>> from pymongo import MongoClient
>>> from gridfs import GridFS
>>> from bson import objectid
>>> db = MongoClient().test
>>> fs = GridFS(db)
>>> with open("/tmp/dictionary") as dictionary:
...   uid = fs.put(dictionary)

错误

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/local/lib/python3.5/site-packages/gridfs/__init__.py", line 122, in put
    grid_file.write(data)
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 365, in write
    self.__flush_data(to_write)
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 257, in __flush_data
    self._file['md5'].update(data)
TypeError: Unicode-objects must be encoded before hashing

>>> ob = fs.put("hello world")


Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 337, in write
    read = data.read
AttributeError: 'str' object has no attribute 'read'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 344, in write
    data = data.encode(self.encoding)
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 235, in __getattr__
    raise AttributeError("GridIn object has no attribute '%s'" % name)
AttributeError: GridIn object has no attribute 'encoding'

在处理上述异常的过程中,又发生了一个异常:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/site-packages/gridfs/__init__.py", line 122, in put
    grid_file.write(data)
  File "/usr/local/lib/python3.5/site-packages/gridfs/grid_file.py", line 347, in write
    "order to write %s" % (text_type.__name__,))
TypeError: must specify an encoding for file in order to write str

mongofiles 的工作示例

[xxxx@yyyy]$ mongofiles put /tmp/dictionary
018-01-21T07:46:36.914-0800 connected to: localhost
added file: /tmp/dictionary
[xxxx@yyyy]$ mongofiles list
2018-01-21T07:46:40.885-0800    connected to: localhost
/tmp/dictionary 4953699
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
/tmp/dictionary 4953699
[xxxx@yyyy]$ mongo
MongoDB shell version v3.6.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.1
<snip>
> db.fs.files.find()
 "_id" : ObjectId("5a633e0f50fe750b83159c55"), "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-20T13:03:11.640Z"), "length" : 4953699, "md5" : "40c0825855792bd20e8a2d515fe9c3e3", "filename" : "/tmp/dictionary" 
 "_id" : ObjectId("5a649cc350fe75402441749c"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T13:59:31.947Z") 
 "_id" : ObjectId("5a649f2150fe7540f6fbe2bf"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "uploadDate" : ISODate("2018-01-21T14:09:37.428Z"), "chunkSize" : 261120, "length" : 0 
 "_id" : ObjectId("5a64a06850fe7540f6fbe2c0"), "encoding" : "utf-8", "md5" : "d41d8cd98f00b204e9800998ecf8427e", "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T14:15:04.993Z"), "length" : 0 
 "_id" : ObjectId("5a64a36b50fe7541e001ab63"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "chunkSize" : 261120, "length" : 0, "uploadDate" : ISODate("2018-01-21T14:27:55.166Z") 
 "_id" : ObjectId("5a64a6ba50fe754250c7ef4b"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "uploadDate" : ISODate("2018-01-21T14:42:02.976Z"), "chunkSize" : 261120 
 "_id" : ObjectId("5a64a70750fe754250c7ef4c"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "uploadDate" : ISODate("2018-01-21T14:43:19.887Z"), "chunkSize" : 261120 
 "_id" : ObjectId("5a64a72750fe754250c7ef4d"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "uploadDate" : ISODate("2018-01-21T14:43:51.084Z"), "chunkSize" : 261120 
 "_id" : ObjectId("5a64abd850fe754301c8b2d2"), "length" : 0, "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T15:03:52.886Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e" 
 "_id" : ObjectId("5a64ac4950fe754301c8b2d3"), "length" : 0, "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T15:05:45.734Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e" 
 "_id" : ObjectId("5a64acf750fe754301c8b2d4"), "length" : 0, "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T15:08:39.102Z"), "md5" : "d41d8cd98f00b204e9800998ecf8427e" 
 "_id" : ObjectId("5a64adc150fe754411469314"), "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T15:12:01.892Z") 
 "_id" : ObjectId("5a64b1b850fe7544ac42cde3"), "chunkSize" : 261120, "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "uploadDate" : ISODate("2018-01-21T15:28:56.951Z") 
 "_id" : ObjectId("5a64b2c550fe7544ac42cde4"), "chunkSize" : 261120, "md5" : "d41d8cd98f00b204e9800998ecf8427e", "length" : 0, "uploadDate" : ISODate("2018-01-21T15:33:25.168Z") 
 "_id" : ObjectId("5a64b5dc50fe7545bbffcbdb"), "chunkSize" : 261120, "uploadDate" : ISODate("2018-01-21T15:46:37.023Z"), "length" : 4953699, "md5" : "40c0825855792bd20e8a2d515fe9c3e3", "filename" : "/tmp/dictionary" 
>

【问题讨论】:

【参考方案1】:

gridfs.GridFS.put 应该传递一个以二进制模式打开的文件。

with open('/tmp/dictionary', 'rb') as dictionary:
    uid = fs.put(dictionary)

您还可以传递str 对象。但是,您需要传递编码关键字参数。

with open('newtmp') as f:
    uid = fs.put(f.read(), encoding='utf-8')

请注意这与 Python 3 相关,因为 strunicodebytes 之间的区别

【讨论】:

以上是关于Pymongo GridFS 放置类型/属性错误的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 PyMongo 和 Bottle 显示来自 MongoDB 数据库的图像?

如何在 PyMongo 的 GridFS 中打开文件的 GridOut 实例?

使用烧瓶中的 send_file() 时文件损坏,pymongo gridfs 中的数据

pymongo 无法检索文件

gridfs "list" 方法返回非空集合的空列表

使用Python将MongoDB的GirdFS的文件导出