做了个项目,需要用mongodb ,查了许多资料,现在整理一下,做个笔记。
1、安装mongodb再网上可以查到,这个就不做记录了(懒得打字)
2、python 使用mongodb
mongodb 可以保存文件和文档,具体的结构请看上一篇博文。
现在上代码
python导入mongodb 的库
from pymongo import MongoClient #mongo客户端
from pymongo.errors import ConnectionFailure #错误类型
from gridfs import GridFS #文件储存
from gridfs.errors import FileExists #出错类型
建立一个类,再类里有连接和处理方法
class MongoDB(object): #建立mongo类(名字随便)
def connect(self): #连接到mongo的方法
try:
self.conn=MongoClient("127.0.0.1",27017) #连接到mongo
self.db=self.conn["crack"] #建立crack 数据库(名字随意),mongodb里面没有此库的话就新建
self.coll_set=self.db["report"] #建立report 集合,同上,(这个集合和下面的fs集合看需求选择,因本人都需要所以建立两个集合,存储大型文件的话需要下面的就够了)
self.fs=GridFS(self.db) #在crack 数据库里建立GridFS文件集合(可以这么理解吧,专业名词不知道怎么说)产生两个集合,fs.files,fs.chunks
def store_file(self,file_obj,report,filename=""):#存储文件方法,file_obj是mongodb处理文件的类,因为mongo存如文件需要文件的MD5等数据
if not filename:
filename=file_obj.get_name()
#store_file
#print file_obj.file_path
#print file_obj.get_md5()
existing = self.db.fs.files.find_one({"md5":file_obj.get_md5()})#到crack数据库的fs.files文件集合找对应的数据
if existing:
if self.coll_set.find_one({"file_path":file_obj.file_path})["crack_status"] == "cracked":#到report集合找数据
return existing["_id"]
new = self.fs.new_file(filename=filename,
contenType=file_obj.get_content_type(),
md5=file_obj.get_md5())#fs.files文件集合建新文件数据
for chunk in file_obj.get_chunks():#fs.chunks文件集合存文件
new.write(chunk)
self.coll_set.insert({"file_id":new._id,"crack_status":"uncrack","file_path":file_obj.file_path,
"crack_info":"","md5":file_obj.get_md5(),"deep_info":report})#report集合插入自定义数据
try:
new.close()
#print "new file"
return new._id
except FileExists:
to_find={"md5":file_obj.get_md5()}
return self.db.fs.files.find_one(to_find)["_id"]
def find_report(self,md5):#查找report集合数据
file_report=self.coll_set.find_one({"md5":md5})
if not file_report:
return None
if file_report["crack_status"] == "uncrack":
return None
return file_report
def find_file(self,md5):#查找fs.files数据
existing = self.db.fs.files.file_one({"md5":md5})
if existing:
return existing["_id"]
else:
return None
def find_uncrack(self):#查找report集合里满足条件的数据
uncrack_list=[]
for i in self.coll_set.find({"crack_status":"uncrack"}):
if not i :
return None
uncrack_list.append(i)
return uncrack_list
def update_cracked(self,report,crack_info):#更新数据库数据
self.coll_set.update(report,{"$set":{"crack_status":"cracked"}})
self.coll_set.update({"file_id":report.get("file_id")},{"$set":{"crack_info":crack_info}})
print self.coll_set.find_one({"file_path":report.get("file_path")})
def update_test(self,report,info):#同上,测试使用
self.coll_set.update(report,{"$set":{"crack_info":info}})
print self.coll_set.find_one({"file_path":report.get("file_path")})
def run(self,file_path,report):#连接mongo
if not HAVE_MONGO:
print (
"Unable to import pymongo (install with "
"`pip install pymongo`)"
)
file_md5=""
self.connect()
file = File(file_path)#这个类是上文说到的文件处理类,这个就不贴出来了,上面需要的get_md5,get_name等方法都是再这个类里
if file.valid():
id=self.store_file(file,report)
self.conn.close()
def clear_files(self):#清空report集合所有数据
self.coll_set.remove()
def clear_file(self,report):#清空符合条件的数据
self.coll_set.remove(report)
def upload_file(self,md5,upload_path=os.getcwd()):#取出保存的文件
report=self.file_report(md5)
if not report:
return None
else:
with open(upload_path,"wb") as fd:
fd.write(self.fs.get(ObjectId(report["files_id"])).read())
#结合其他两篇博文慢慢摸索,就会明白怎么使用了