1. 程式人生 > >python 使用mongodb 資料庫操作

python 使用mongodb 資料庫操作

做了個專案,需要用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())

#結合其他兩篇博文慢慢摸索,就會明白怎麼使用了