ORM-像對象一樣對待數據

咱們編程教室有不少同學,學完了基礎課程,掌握了一定的編程能力,開始做項目了。然後很可能遇到一個問題:管理數據。課程裏有講過用文件保存數據,還有 picklecsv 等模塊輔助。但對於稍微複雜一點的數據,往往不夠方便。成熟的解決方案就是使用 數據庫

估計每個剛剛使用數據庫的人都會被坑得遍體鱗傷。對於一個剛剛學會 Python 不久的開發新手來說,使用數據庫的 SQL 語句 幾乎相當於再學一種新的語言。雖然 sqlitepymysql 等模塊提供了與數據的連接,但仍然需要自己去拼接 SQL 語句。Python 語法和 SQL 語法、各種引號、百分號、轉義字符混雜在一起的酸爽,用過的人都忘不了。

所以實際開發中,如無特殊需求,一般不會直接寫 SQL,而是用更爲方便的 ORM(對象關係映射,Object Relational Mapping) 。顧名思義,就是將關係型數據庫與 Python 中的對象關聯起來,提供了一種操作數據的簡便方式,相當於對數據庫加了一層更友好的接口。

目前 Python 中比較流行的 ORM 解決方案有三種:

  1. Django ORM 。使用方便,但很難脫離 Django 單獨使用。
  2. SQLAlchemy 。功能強大,成熟可擴展,但學習門檻較高。
  3. peewee 。輕量,可擴展,易學習,但功能有限。

對於偏初級的小型項目,通常用不到很複雜的功能,這時候 peewee 或許是最好的選擇。今天我們就來重點介紹下 peewee 這個 Python ORM 庫。

> 安裝



 pip install peewee

> 連接數據庫

以 SQLite 爲例:



import peewee
db = peewee.SqliteDatabase('people.db')
db.connect()

people.db 是 SQLite 的數據庫文件,如果不存在會自己新建。

如果是 MySQL,要稍微複雜點,需再提供地址、用戶名、密碼等信息,並且必須先手動建好庫:



db = peewee.MySQLDatabase('people', host='127.0.0.1', user='root', passwd='', charset='utf8', port=3306)

特別要記住的一點是,代碼進行完所有數據庫操作後,要主動關閉數據庫:



db.close()

> 創建數據類型

既然是與對象關聯,自然需要以面向對象的方式定義數據結構。我們假定一個表示人的類型 Person,包含姓名 name 和生日 birthday 兩個字段:



class Person(peewee.Model):
    class Meta:
        database = db
    name = peewee.CharField()
    birthday = peewee.DateField()

Person.create_table()

如果是用過 Django 的同學,對這個 Model 應該非常熟悉了。要注意的就是,需要在 Meta 裏定義 database 爲前面創建的數據庫。然後使用相應的 Field 類型定義字段即可。

> 新增數據對象



 from datetime import date
# 方法1
uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15))
uncle_bob.save()
# 方法2
Person.create(name='Crossin', birthday=date(1985, 5, 5))

直接創建數據對象,需要調用 save 方法保存到數據庫中。而使用 create 方法創建則不用。

> 查找數據對象



 bob = Person.get(Person.name == 'Bob')
print(bob.name, bob.birthday)
# 獲取所有數據
for person in Person.select():
    print(person.name)

注意這裏的查找條件寫法,這與 Django 是不同的。查找還可以用 where 語句,這裏不做演示,可以參考官方文檔。

> 修改數據對象

對於上一步找到的 bob 變量:



bob.name = 'Robert'
bob.save()

直接向屬性賦值,修改完記得要 save

> 刪除數據對象



 bob.delete_instance()

順便說句,一般不建議在數據庫裏刪除數據,因爲數據刪了就不好找回來了,而且可能還會引發關聯數據的報錯。通常是增加一個 is_deleted 字段標記已刪除的內容。(所以,不要以爲在網上把發佈過的內容刪掉就真的不存在了)

> 創建關聯數據

在程序中,經常會有一些具有關聯關係的數據。比如我們再創建一個寵物類 Pet,每個寵物有名字 name 和主人 owner。owner 對應的就是我們前面創建的 Person 類:



class Pet(peewee.Model):
    class Meta:
        database = db
    owner = peewee.ForeignKeyField(Person, backref='pets')
    name = peewee.CharField()

這樣一來,我們就可以很方便的通過寵物找到它的主人:



bob_kitty = Pet.create(owner=bob, name='Kitty')
bob_fido = Pet.create(owner=bob, name='Fido')
print(bob_kitty.owner.name)

也可以找到一個人養的所有寵物:



for pet in bob.pets:
    print(pet.name)

以上就是 peewee 的基本操作,如果你瞭解面向對象,應該不難理解。這些例子取自其官方文檔的快速上手 Quickstart。雖然沒有像 Requests 那樣貼心地提供中文版,但也同樣足夠人性化。

地址:http://docs.peewee-orm.com/en/latest/peewee/quickstart.html

> 自動生成代碼

peewee 提供了一個功能,可以從已有的數據庫反向生成數據模型代碼。以 SQLite 爲例:



python -m pwiz -e sqlite people.db > db.py

在你的數據庫文件所在路徑下執行這條命令,就可以在 db.py 中自動生成代碼。

自動生成的代碼

在本專欄先前的案例中,有一些就使用了 peewee。比如 Python 高頻詞彙表 (關鍵字: 單詞 )和 押韻檢索工具 (關鍵字: 押韻 )。在本公衆號( Crossin的編程教室 )裏回覆相應關鍵字可查看文章及代碼。

最後提一下,除了使用 ORM 外,對於數據存儲還有一種解決方案,就是使用非關係型數據庫,比如 mongodb 。儘管坑也不少,但對於簡單的數據存儲來說,它有個巨大的優勢就是 同 Python 內置的 dict、list 等類型兼容良好 ,可以直接存取,讓你甚至感覺不到有數據庫的存在,也根本無需關心 SQL 語句。爬蟲實戰課程中的部分案例,就選擇了 mongodb 作爲數據存儲方案。

════
其他文章及回答:

如何自學Python | 新手引導 | 精選Python問答 | Python單詞表 | 區塊鏈 | 人工智能 | 雙11 | 嘻哈 | 爬蟲 | 排序算法 | 我用Python | 高考 | 世界盃 | requests

歡迎搜索及關注: Crossin的編程教室

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章