九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
在 Python 應(yīng)用中使用 MongoDB

譯文:開源中國社區(qū)  j_hao104

鏈接:https://my.oschina.net/jhao104/blog/812002(點擊尾部閱讀原文前往)

原文:https://realpython.com/blog/python/introduction-to-mongodb-and-python


Python是開發(fā)社區(qū)中用于許多不同類型應(yīng)用的強大編程語言。很多人都知道它是可以處理幾乎任何任務(wù)的靈活語言。因此,在Python應(yīng)用中需要一個什么樣的與語言本身一樣靈活的數(shù)據(jù)庫呢?那就是NoSQL,比如MongoDB。


在這篇文章中,將向您展示如何使用Python鏈接目前主流的MongoDB(V3.4.0)數(shù)據(jù)庫,主要使用PyMongo(v3.4.0)和MongoEngine(V0.10.7)。同時比較SQL和NoSQL。


1、SQL vs NoSQL


如果你不是很熟悉NoSQL這個概念,MongoDB就是一個NoSQL數(shù)據(jù)庫。近幾年來它越來越受到整個行業(yè)的歡迎。NoSQL數(shù)據(jù)庫提供了一個和關(guān)系型數(shù)據(jù)庫非常不同的檢索方式和存儲數(shù)據(jù)功能。


在NoSQL出現(xiàn)的幾十年來,SQL數(shù)據(jù)庫是開發(fā)者尋求構(gòu)建大型、可擴展系統(tǒng)的唯一選擇之一。然而,越來越多的需求要求存儲復(fù)雜數(shù)據(jù)結(jié)構(gòu)的能力。這推動了NoSQL數(shù)據(jù)庫的誕生,它允許開發(fā)者存儲異構(gòu)和無結(jié)構(gòu)的數(shù)據(jù)。


當(dāng)?shù)綌?shù)據(jù)庫方案選擇時,大多數(shù)人都問自己最后一個問題,“SQL或NoSQL的?”。無論是SQL和NoSQL都有自己的長處和弱點,你應(yīng)該選擇適合您的應(yīng)用需求中最好的之一。這里是兩者之間的一些區(qū)別:


SQL


  • 模型是關(guān)系型的;

  • 數(shù)據(jù)被存放在表中;

  • 適用于每條記錄都是相同類型并具有相同屬性的情況;

  • 存儲規(guī)范需要預(yù)定義結(jié)構(gòu);

  • 添加新的屬性意味著你必須改變整體架構(gòu);

  • ACID事務(wù)支持;


NoSQL


  • 模型是非關(guān)系型的;

  • 可以存儲Json、鍵值對等(決定于NoSQL數(shù)據(jù)庫類型);

  • 并不是每條記錄都要有相同的結(jié)構(gòu);

  • 添加帶有新屬性的數(shù)據(jù)時,不會影響其他;

  • 支持ACID事務(wù),根據(jù)使用的NoSQL的數(shù)據(jù)庫而有所不同;

  • 一致性可以改變;

  • 橫向擴展;


在兩種類型的數(shù)據(jù)庫之間還有許多其他的區(qū)別,但上面提到的是一些更重要的區(qū)別。根據(jù)您的具體情況,使用SQL數(shù)據(jù)庫可能是首選,而在其他情況下,NoSQL的是更明顯的選擇。當(dāng)選擇一個數(shù)據(jù)庫時,您應(yīng)該謹(jǐn)慎考慮每個數(shù)據(jù)庫的優(yōu)勢和劣勢。


NoSQL的一個好處是,有許多不同類型的數(shù)據(jù)庫可供選擇,并且每個都有自己的用例:


在兩種類型的數(shù)據(jù)庫之間還有許多其他的區(qū)別,但上面提到的是一些更重要的區(qū)別。根據(jù)您的具體情況,使用SQL數(shù)據(jù)庫可能是首選,而在其他情況下,NoSQL的是更明顯的選擇。當(dāng)選擇一個數(shù)據(jù)庫時,您應(yīng)該謹(jǐn)慎考慮每個數(shù)據(jù)庫的優(yōu)勢和劣勢。


NoSQL的一個好處是,有許多不同類型的數(shù)據(jù)庫可供選擇,并且每個都有自己的用例:


  • key-value存儲:DynamoDB

  • 文檔存儲:CouchDB,MongoDB,RethinkDB

  • 列存儲:Cassandra

  • 數(shù)據(jù)結(jié)構(gòu): Redis,SSDB


還有很多,但這些是一些更常見的類型。近年來,SQL和NoSQL數(shù)據(jù)庫甚至已經(jīng)開始合并。例如,PostgreSQL現(xiàn)在支持存儲和查詢JSON數(shù)據(jù),很像MongoDB。有了這個,你可以用Postgres實現(xiàn)MongoDB一樣的功能,但你仍然沒有MongoDB的其他優(yōu)勢(如橫向擴容和簡單的界面,等等)。


2、MongoDB


現(xiàn)在,讓我們將視線轉(zhuǎn)移到本文的重點,并闡明的MongoDB的具體的一些情況。


MongoDB是一個面向文檔的,開源數(shù)據(jù)庫程序,它平臺無關(guān)。MongoDB像其他一些NoSQL數(shù)據(jù)庫(但不是全部!)使用JSON結(jié)構(gòu)的文檔存儲數(shù)據(jù)。這是使得數(shù)據(jù)非常靈活,不需要的Schema。


一些比較重要的特點是:


  • 支持多種標(biāo)準(zhǔn)查詢類型,比如matching()、comparison (, )或者正則表達(dá)式;

  • 可以存儲幾乎任何類型的數(shù)據(jù),無論是結(jié)構(gòu)化,部分結(jié)構(gòu)化,甚至是多態(tài);

  • 要擴展和處理更多查詢,只需添加更多的機器;

  • 它是高度靈活和敏捷,讓您能夠快速開發(fā)應(yīng)用程序;

  • 作為基于文檔的數(shù)據(jù)庫意味著您可以在單個文檔中存儲有關(guān)您的模型的所有信息;

  • 您可以隨時更改數(shù)據(jù)庫的Schema;

  • 許多關(guān)系型數(shù)據(jù)庫的功能也可以在MongoDB使用(如索引)。


在運行方面,MongoDB中有相當(dāng)多的功能在其他數(shù)據(jù)庫中是沒有的:


  • 無論您需要獨立服務(wù)器還是完整的獨立服務(wù)器集群,MongoDB都可以根據(jù)需要進(jìn)行擴展;

  • MongoDB還通過在各個分片上自動移動數(shù)據(jù)來提供負(fù)載均衡支持;

  • 它具有自動故障轉(zhuǎn)移支持,如果主服務(wù)器Down掉,新的主服務(wù)器將自動啟動并運行;

  • MongoDB的管理服務(wù)(MMS)可以用于監(jiān)控和備份MongoDB的基礎(chǔ)設(shè)施服務(wù);

  • 不像關(guān)系數(shù)據(jù)庫,由于內(nèi)存映射文件,你將節(jié)省相當(dāng)多的RAM。


雖然起初MongoDB似乎是解決我們許多問題的數(shù)據(jù)庫,但它不是沒有缺點的。MongoDB的一個常見缺點是缺少對ACID事務(wù)的支持,MongoDB在特定場景下支持ACID事務(wù),但不是在所有情況。在單文檔級別,支持ACID事務(wù)(這是大多數(shù)事務(wù)發(fā)生的地方)。但是,由于MongoDB的分布式性質(zhì),不支持處理多個文檔的事務(wù)。


MongoDB還缺少對自然join查詢支持。在MongoDB看來:文檔意在包羅萬象,這意味著,一般來說,它們不需要參考其他文檔。在現(xiàn)實世界中,這并不總是有效的,因為我們使用的數(shù)據(jù)是關(guān)系性的。因此,許多人認(rèn)為MongoDB應(yīng)該被用作一個SQL數(shù)據(jù)庫的補充數(shù)據(jù)庫,但是當(dāng)你使用MongoDB是,你會發(fā)現(xiàn)這是錯誤的


3、PyMongo


現(xiàn)在我們已經(jīng)描述了MongoDB的是什么,讓我們來看看如何在Python中實際使用它。由MongoDB開發(fā)者發(fā)布的官方驅(qū)動程序PyMongo,這里通過一些例子介紹,但你也應(yīng)該查看完整的文檔,因為我們無法面面俱到。


當(dāng)然第一件事就是安裝,最簡單的方式就是pip:


pip install pymongo==3.4.0


注:有關(guān)更全面的指南,請查看文檔的安裝/升級頁面,并按照其中的步驟進(jìn)行設(shè)置


完成設(shè)置后,啟動的Python控制臺并運行以下命令:


>>> import pymongo


如果沒有提出任何異常就說明安裝成功了


建立連接


使用MongoClient對象建立連接:


from pymongo import MongoClient

client = MongoClient()


使用上面的代碼片段,將建立連接到默認(rèn)主機(localhost)和端口(27017)。您還可以指定主機和/或使用端口:


client = MongoClient('localhost', 27017)


或者使用MongoURl格式:


client = MongoClient('mongodb://localhost:27017')


訪問數(shù)據(jù)庫


一旦你有一個連接的MongoClient實例,你可以在Mongo服務(wù)器中訪問任何數(shù)據(jù)庫。如果要訪問一個數(shù)據(jù)庫,你可以當(dāng)作屬性一樣訪問:


db = client.pymongo_test


或者你也可以使用字典形式的訪問:


db = client['pymongo_test']


如果您的指定數(shù)據(jù)庫已創(chuàng)建,實際上并不重要。通過指定此數(shù)據(jù)庫名稱并將數(shù)據(jù)保存到其中,您將自動創(chuàng)建數(shù)據(jù)庫。


插入文檔


在數(shù)據(jù)庫中存儲數(shù)據(jù),就如同調(diào)用只是兩行代碼一樣容易。第一行指定你將使用哪個集合。在MongoDB中術(shù)語中,一個集合是在數(shù)據(jù)庫中存儲在一起的一組文檔(相當(dāng)于SQL的表)。集合和文檔類似于SQL表和行。第二行是使用集合插入數(shù)據(jù)insert_one()的方法:


posts = db.posts

post_data = {

    'title''Python and MongoDB',

    'content''PyMongo is fun, you guys',

    'author''Scott'

}

result = posts.insert_one(post_data)

print('One post: {0}'.format(result.inserted_id))


我們甚至可以使用insert_one()同時插入很多文檔,如果你有很多的文檔添加到數(shù)據(jù)庫中,可以使用方法insert_many()。此方法接受一個list參數(shù):


post_1 = {

    'title''Python and MongoDB',

    'content''PyMongo is fun, you guys',

    'author''Scott'

}

post_2 = {

    'title''Virtual Environments',

    'content''Use virtual environments, you guys',

    'author''Scott'

}

post_3 = {

    'title''Learning Python',

    'content''Learn Python, it is easy',

    'author''Bill'

}

new_result = posts.insert_many([post_1, post_2, post_3])

print('Multiple posts: {0}'.format(new_result.inserted_ids))


你應(yīng)該看到類似輸出:


One post584d947dea542a13e9ec7ae6

Multiple posts[

    ObjectId('584d947dea542a13e9ec7ae7'),

    ObjectId('584d947dea542a13e9ec7ae8'),

    ObjectId('584d947dea542a13e9ec7ae9')

]


注意: 不要擔(dān)心,你和上面顯示不一樣。它們是在插入數(shù)據(jù)時,由Unix的紀(jì)元,機器標(biāo)識符和其他唯一數(shù)據(jù)組成的動態(tài)標(biāo)識。


檢索文檔


檢索文檔可以使用find_one()方法,比如要找到author為Bill的記錄:


bills_post = posts.find_one({'author''Bill'})

print(bills_post)

 

運行結(jié)果:

{

    'author''Bill',

    'title''Learning Python',

    'content''Learn Python, it is easy',

    '_id'ObjectId('584c4afdea542a766d254241')

}


您可能已經(jīng)注意到,這篇文章的ObjectId是設(shè)置的_id,這是以后可以使用唯一標(biāo)識。如果需要查詢多條記錄可以使用find()方法:


scotts_posts = posts.find({'author''Scott'})

print(scotts_posts)

 

結(jié)果:

pymongo.cursor.Cursor object at 0x109852f98>


他的主要區(qū)別在于文檔數(shù)據(jù)不是作為數(shù)組直接返回給我們。相反,我們得到一個游標(biāo)對象的實例。這Cursor是一個包含相當(dāng)多的輔助方法,以幫助您處理數(shù)據(jù)的迭代對象。要獲得每個文檔,只需遍歷結(jié)果:


for post in scotts_posts:

    print(post)


4、MongoEngine


雖然PyMongo是非常容易使用,總體上是一個偉大的輪子,但是許多項目使用它都可能太低水平。簡而言之,你必須編寫很多自己的代碼來持續(xù)地保存,檢索和刪除對象。PyMongo之上提供了一個更高的抽象一個庫是MongoEngine。MongoEngine是一個對象文檔映射器(ODM),它大致相當(dāng)于一個基于SQL的對象關(guān)系映射器(ORM)。MongoEngine提供的抽象是基于類的,所以你創(chuàng)建的所有模型都是類。雖然有相當(dāng)多的Python的庫可以幫助您使用MongoDB,MongoEngine是一個更好的,因為它有一個很好的組合的功能,靈活性和社區(qū)支持。


使用pip安裝:


pip install mongoengine==0.10.7


連接:


from mongoengine import *

connect('mongoengine_test', host='localhost', port=27017)


和pymongo不同。MongoEngine需要制定數(shù)據(jù)庫名稱。


定義文檔


建立文檔之前,需要定義文檔中要存放數(shù)據(jù)的字段。與許多其他ORM類似,我們將通過繼承Document類,并提供我們想要的數(shù)據(jù)類型來做到這一點:


import datetime

 

class Post(Document):

    title = StringField(required=True, max_length=200)

    content = StringField(required=True)

    author = StringField(required=True, max_length=50)

    published = DateTimeField(default=datetime.datetime.now)


在這個簡單的模型中,我們已經(jīng)告訴MongoEngine,我們的Post實例有title、content、author、published?,F(xiàn)在Document對象可以使用該信息來驗證我們提供它的數(shù)據(jù)。


因此,如果我們試圖保存Post的中沒有title那么它會拋出一個Exception,讓我們知道。我們甚至可以進(jìn)一步利用這個并添加更多的限制:


  • required:設(shè)置必須;

  • default:如果沒有其他值給出使用指定的默認(rèn)值

  • unique:確保集合中沒有其他document有此字段的值相同

  • choices:確保該字段的值等于數(shù)組中的給定值之一


保存文檔


將文檔保存到數(shù)據(jù)庫中,我們將使用save()的方法。如果文檔中的數(shù)據(jù)庫已經(jīng)存在,則所有的更改將在原子水平上對現(xiàn)有的文檔進(jìn)行。如果它不存在,但是,那么它會被創(chuàng)建。


這里是創(chuàng)建和保存一個文檔的例子:


post_1 = Post(

    title='Sample Post',

    content='Some engaging content',

    author='Scott'

)

post_1.save()       # This will perform an insert

print(post_1.title)

post_1.title = 'A Better Post Title'

post_1.save()       # This will perform an atomic edit on 'title'

print(post_1.title)


調(diào)用save()的時候需要注意幾點:


  • PyMongo將在您調(diào)用.save()時執(zhí)行驗證,這意味著它將根據(jù)您在類中聲明的模式檢查要保存的數(shù)據(jù),如果違反模式(或約束),則拋出異常并且不保存數(shù)據(jù);

  • 由于Mongo不支持真正的事務(wù),因此沒有辦法像在SQL數(shù)據(jù)庫中那樣“回滾”.save()調(diào)用。


當(dāng)你保存的數(shù)據(jù)沒有title時:


post_2 = Post(content='Content goes here', author='Michael')

post_2.save()

 

raise ValidationError(message, errors=errors)

mongoengine.errors.ValidationError:

ValidationError (Post:None) (Field is required['title'])


向?qū)ο蟮奶匦?/strong>


使用MongoEngine是面向?qū)ο蟮模阋部梢蕴砑臃椒ǖ侥愕淖宇愇臋n。例如下面的示例,其中函數(shù)用于修改默認(rèn)查詢集(返回集合的所有對象)。通過使用它,我們可以對類應(yīng)用默認(rèn)過濾器,并只獲取所需的對象


class Post(Document):

    title = StringField()

    published = BooleanField()

 

    @queryset_manager

    def live_posts(clazz, queryset):

        return queryset.filter(published=True)


關(guān)聯(lián)其他文檔


您還可以使用ReferenceField對象來創(chuàng)建從一個文檔到另一個文檔的引用。MongoEngine在訪問時自動惰性處理引用。


class Author(Document):

    name = StringField()

 

class Post(Document):

    author = ReferenceField(Author)

 

Post.objects.first().author.name


在上面的代碼中,使用文檔”外鍵”,我們可以很容易地找到第一篇文章的作者。其實還有比這里介紹的更多的字段類(和參數(shù)),所以一定要查看文檔字段更多信息。


從所有這些示例中,您應(yīng)該能夠看到,MongoEngine非常適合管理幾乎任何類型的應(yīng)用程序的數(shù)據(jù)庫對象。這些功能使得創(chuàng)建一個高效可擴展程序變得非常容易。如果你正在尋找更多關(guān)于MongoEngine的幫助,請務(wù)必查閱他們的用戶指南。



●本文編號112,以后想閱讀這篇文章直接輸入112即可。

●輸入m可以獲取到文章目錄

相關(guān)推薦↓↓↓
 

大數(shù)據(jù)技術(shù)

推薦15個技術(shù)類公眾微信

涵蓋:程序人生、算法與數(shù)據(jù)結(jié)構(gòu)、黑客技術(shù)與網(wǎng)絡(luò)安全、大數(shù)據(jù)技術(shù)、前端開發(fā)、Java、Python、Web開發(fā)、安卓開發(fā)、iOS開發(fā)、C/C++、.NET、Linux、數(shù)據(jù)庫、運維

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
最全總結(jié) | 聊聊 Python 數(shù)據(jù)處理全家桶(MongoDB 篇)
Python淺談-Python操作數(shù)據(jù)庫之MongoDB
數(shù)據(jù)庫的 N 多騷操作了解一下?
幾種Python 數(shù)據(jù)讀寫方式,面向Txt、csv文檔及MongoDB、MySQL等數(shù)據(jù)庫
一文讀懂 MongoDB 和 MySQL 的差異
視覺中國的NoSQL之路:從MySQL到MongoDB
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服