折腾:
【已解决】如何用PyMongo中的GridFS的put去保存添加文件
期间,用代码:
<code>
mongoClient = MongoClient()
logging.info("mongoClient=%s", mongoClient)
gridfsDb = mongoClient.gridfs
logging.info("gridfsDb=%s", gridfsDb)
collectionNames = gridfsDb.collection_names(include_system_collections=False)
logging.info("collectionNames=%s", collectionNames)
# fsCollection = gridfsDb.fs
fsCollection = gridfsDb["fs"]
logging.info("fsCollection=%s", fsCollection)
someFile = fsCollection.files.find_one()
logging.info("someFile=%s", someFile)
# test read existed file info
ottoTheCatFile = fsCollection.files.find_one({"filename": "Otto the Cat-withMIME.MP3"})
logging.info("ottoTheCatFile=%s", ottoTheCatFile)
# test put local file
curAudioFilename = "英语资源\All Aboard Reading\音频\Lots of Hearts.mp3"
curAudioFilenameFiltered = re.sub(r"\\", "/", curAudioFilename) #'英语资源/All Aboard Reading/音频/Lots of Hearts.mp3'
# curAudioFullFilename = "/Users/crifan/dev/dev_root/company/naturling/数据/FromMaggie/" + curAudioFilename
pathPrefix = "/Users/crifan/dev/dev_root/company/naturling/数据/FromMaggie/"
curAudioFullFilename = os.path.join(pathPrefix, curAudioFilenameFiltered)
if os.path.isfile(curAudioFullFilename):
with open(curAudioFullFilename) as audioFp :
audioFileId = fsCollection.put(audioFp,
filename="Lots of Hearts_withMIME.mp3",
content_type="application/mpeg")
logging.info("audioFileId=%s", audioFileId)
else:
logging.error("Can not find file: %s", curAudioFullFilename)
</code>运行出错:

<code>Traceback (most recent call last):
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1668, in <module>
main()
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1662, in main
globals = debugger.run(setup['file'], None, None, is_module)
File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1072, in run
pydev_imports.execfile(file, globals, locals) # execute the script
File "/Users/crifan/dev/dev_root/company/naturling/projects/mongodb/saveLocalData/pymongoTest.py", line 66, in <module>
content_type="application/mpeg")
File "/usr/local/lib/python2.7/site-packages/pymongo/collection.py", line 3104, in __call__
self.__name.split(".")[-1])
TypeError: 'Collection' object is not callable. If you meant to call the 'put' method on a 'Collection' object it is failing because no such method exists.
</code>难道是with 内部,无法识别外部的变量fsCollection?
或者是 此处fsCollection用法不正确,没有put?
pymongo TypeError: ‘Collection’ object is not callable
python – Collection object is not callable error with PyMongo – Stack Overflow
python – ‘Collection’ object is not callable error in pymongo with process Pool – Stack Overflow
python – PyMongo Collection Object Not Callable – Stack Overflow
Pymongo troubles – Collection Object is not callable:mongodb
TypeError: ‘Collection’ object is not callable. · Issue #211 · mzupan/nagios-plugin-mongodb

看起来貌似没问题啊
此处fs的collection,PyCharm中无法动态识别源码:


看起来此处的:
fsCollection是:Collection(Database(MongoClient(host=[‘localhost:27017′], document_class=dict, tz_aware=False, connect=True), u’gridfs’), u’fs’)
然后换用之前别处代码的写法:
<code># fsCollection = gridfsDb["fs"] fsCollection = GridFS(gridfsDb) </code>
看看是否有变化:


果然看起来就像对的:
<gridfs.GridFS object at 0x10563cc90>
看起来这个才是PyMongo支持的对象
然后接着再去操作试试
此时,之前的代码:
<code>fsCollection.files.find_one() </code>
就会报错了:
<code>Traceback (most recent call last): File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1668, in <module> main() File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1662, in main globals = debugger.run(setup['file'], None, None, is_module) File "/Applications/PyCharm.app/Contents/helpers/pydev/pydevd.py", line 1072, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/Users/crifan/dev/dev_root/company/naturling/projects/mongodb/saveLocalData/pymongoTest.py", line 47, in <module> someFile = fsCollection.files.find_one() AttributeError: 'GridFS' object has no attribute 'files' </code>
去改为:
<code># someFile = fsCollection.files.find_one() someFile = fsCollection.find_one() </code>
结果就可以了:

然后接着代码就正常了,可以put去保存文件了:

【总结】
此处之所以报错:
<code>TypeError: 'Collection' object is not callable. If you meant to call the 'put' method on a 'Collection' object it is failing because no such method exists. </code>
是因为:
此处写的代码,是按照自己之前在MongoDB的命令行中操作的逻辑去用:
<code>fsCollection = gridfsDb.fs </code>
或
<code>fsCollection = gridfsDb["fs”] </code>
得到的是Collection类型变量,之后去:
<code>someFile = fsCollection.files.find_one() </code>
也都没问题。
但是对于:
<code>fsCollection.put </code>
就报错了。因为本身没有put。
而此处已经用的是MongoDB的Python的driver:PyMongo,其标准写法是:
<code>fsCollection = GridFS(gridfsDb) </code>
以及:
<code>someFile = fsCollection.find_one() </code>
然后才有:
<code>if os.path.isfile(curAudioFullFilename): with open(curAudioFullFilename) as audioFp : audioFileId = fsCollection.put(audioFp, filename="Lots of Hearts_withMIME.mp3", content_type="application/mpeg") </code>
才能正常打开本地的文件,去put保存。
转载请注明:在路上 » 【已解决】PyMongo的GridFS中使用fs的collection去put出错:TypeError Collection object is not callable