像對象一樣對待數據

像對象一樣對待數據

來自專欄 Crossin的編程教室

咱們編程教室有不少同學,學完了基礎課程,掌握了一定的編程能力,開始做項目了。然後很可能遇到一個問題:管理數據。課程里有講過用文件保存數據,還有 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 peeweedb = 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# 方法1uncle_bob = Person(name=Bob, birthday=date(1960, 1, 15))uncle_bob.save()# 方法2Person.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 = Robertbob.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 那樣貼心地提供中文版,但也同樣足夠人性化。

地址:docs.peewee-orm.com/en/

> 自動生成代碼

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的編程教室


推薦閱讀:

《中華詩詞三百首》教學參考資料庫之十九
資料庫面試題(開發者必看)
從《SQL必知必會》入門資料庫
OceanBase|官網上線|試用版下載
SQL 壓力測試實戰篇

TAG:Python | 資料庫 | SQL |