peewee 中文翻譯文檔
翻譯:黑洞
Release 2.4.0
始譯於:2017.06.16
目錄
1. 安裝和測試
大多數用戶更願意採用簡單的方式來安裝最新版本的peewee程序, 程序託管在PyPI上:
pip install peewee
1.1 使用 git進行安裝
本項目託管在地址 https://github.com/coleifer/peewee上,用戶可以使用git進行安裝。
git clone https://github.com/coleifer/peewee.git
cd peewee
python setup.py install
注意: 在某些系統上你可能需要使用:sudo python setup.py install 去安裝peewee全系統環境
1.2 進行測試
你可以使用如下命令對你的安裝結果進行測試:
python setup.py test
# 或者使用測試runner程序
python runtests.py
你可以使用runtests.py 腳本測試特定的功能或者特定的數據庫驅動. 默認情況下測試套件的運行使用的是SQLite數據庫,playhouse擴展測試不會運行。要查看可用的測試運行器選項,請使用:
python runtests.py --help
2. 快速開始
2.1 進行測試
本文檔提供了一個簡短而高層次概述的Peewee主要特點描述。本指南將涵蓋:
•模型定義
•存儲數據
•檢索數據
注意:如果你想要更多的乾貨,這裏有一個更加深入的教程:創建一個“推特”風格的Web應用程序通過使用Peewee和Flask框架。
我強烈建議打開交互式shell會話運行代碼,這樣你才能感受到輸入查詢的過程。
2.2 模型定義
每一個模型類將直接映射到某一個數據庫表,每個字段將映射到該表上的某一列,每一個模型實例對應於表中的某一行。
from peewee import *
db= SqliteDatabase(’people.db’)
classPerson(Model):
name = CharField()
birthday = DateField()
is_relative = BooleanField()
class Meta:
database = db # This model uses the"people.db" database.
Peewee中有許多字段類型適合存儲各種類型的數據。Peewee將會處理python和數據庫之間的值轉換的問題,這樣您就可以在代碼中使用Python類型而不必擔心了。
當我們使用外鍵建立模型之間的關係時,Peewee很容易做到
class Pet(Model):
owner = ForeignKeyField(Person,related_name=’pets’)
name = CharField()
animal_type = CharField()
classMeta:
database = db # this model uses the peopledatabase
現在我們有了模型,讓我們創建數據庫中的表來存儲數據。一下命令將創建帶有適當的列、索引、序列和外鍵約束的表:
>>> db.create_tables([Person, Pet])
2.2 存儲數據
讓我們開始人工填充一些數據到數據庫。我們將使用save()和create()方法添加更新Person的記錄。
>>> fromdatetimeimport date
>>>uncle_bob = Person(name=’Bob’, birthday=date(1960, 1, 15), is_relative=True)
>>>uncle_bob.save() # bob is now stored in the database
注意:當你調用save()方法的時候,將會返回改變後的行數。
你也可以通過調用create()方法添加一個人,它會返回一個模型實例:
>>>grandma = Person.create(name=’Grandma’,birthday=date(1935, 3, 1), is_relative=True)
>>>herb = Person.create(name=’Herb’, birthday=date(1950, 5, 5), is_relative=False)
更新、修改模型的實例並調用save()方法使更改生效。在這裏,我們將改變Grandma的名字然後將更改後的數據保存到數據庫中。
>>>grandma.name = ’Grandma L.’
>>>grandma.save() # Update grandma’s name in the database.
1
現在我們已經在數據庫中存儲了3個人。讓我們給他們一些寵物。Grandma不喜歡房子裏的動物,所以她不會有,但Herb是一個動物愛好者:
>>>bob_kitty = Pet.create(owner=uncle_bob, name=’Kitty’,animal_type=’cat’)
>>>herb_fido = Pet.create(owner=herb, name=’Fido’,animal_type=’dog’)
>>>herb_mittens = Pet.create(owner=herb, name=’Mittens’,animal_type=’cat’)
>>>herb_mittens_jr = Pet.create(owner=herb, name=’Mittens Jr’,animal_type=’cat’)
經過很長一段時間的生活後,Mittens生病噁心而且死了。我們需要把它從數據庫中刪除:
>>>herb_mittens.delete_instance() # he had a great life
1
注意:返回數是刪除的行數。
Bob的叔叔決定,太多的動物已經在Herb家死了,所以他接收了Fido:
>>>herb_fido.owner = uncle_bob
>>>herb_fido.save()
>>>bob_fido = herb_fido # rename our variable for clarity
2.2 檢索數據
我們的數據庫的真正實力是允許我們通過查詢檢索數據。關係數據庫對於即席查詢是優秀的。
2.2.1 查詢單個記錄
讓我們從數據庫中檢索Grandma的記錄。若要從數據庫獲得單個記錄,請使用:
SelectQuery.get()方法。
>>>grandma = Person.select().where(Person.name == ’GrandmaL.’).get()
我們還可以使用等效Model.get()方法:
>>>grandma = Person.get(Person.name == ’Grandma L.’)
2.2.1 查詢多個記錄
讓我們列出數據庫中所有的人:
>>> for person in Person.select():
... print person.name, person.is_relative
...
Bob True
Grandma L. True
Herb False
讓我們列出數據庫中所有的貓和其主人:
>>>query = Pet.select().where(Pet.animal_type == ’cat’)
>>> for pet in query:
... print pet.name,pet.owner.name
...
Kitty Bob
Mittens Jr Herb
在之前的查詢中存在一個大問題:因爲我們是訪問pet.owner.name而且在我們原來的查詢中我們沒有選擇這個值,peewee將要執行一個查詢來檢索寵物的主人。這行爲被稱爲N + 1,通常應該避免。
我們可以通過選擇寵物和人並添加連接來避免額外的查詢。
>>>query = (Pet
... .select(Pet, Person)
.. .join(Person)
... .where(Pet.animal_type ==’cat’))
>>> for pet in query:
... print pet.name, pet.owner.name
...
Kitty Bob
Mittens Jr Herb
讓我們獲取所以Bob的寵物:
>>> for pet inPet.select().join(Person).where(Person.name == ’Bob’):
... print pet.name
...
Kitty
Fido
我們可以在這裏做另一件很酷的事來得到Bob的寵物。既然我們已經有一個對象來代表鮑伯,我們可以這麼做:
>>> for pet in Pet.select().where(Pet.owner== uncle_bob):
... print pet.name
通過添加一個order_by()條款讓我們確保這些都是按字母順序排序:
>>> for pet in Pet.select().where(Pet.owner== uncle_bob).order_by(Pet.name):
... print pet.name
...
Fido
Kitty
讓我們從小到老列出所有人:
>>> for person inPerson.select().order_by(Person.birthday.desc()):
... print person.name
...
Bob
Herb
Grandma L.
現在讓我們列出所有的人和一些關於他們寵物的信息:
>>> for person in Person.select():
... print person.name, person.pets.count(), ’pets’
... for pet in person.pets:
... print ’ ’, pet.name,pet.animal_type
...
Bob 2 pets
Kitty cat
Fido dog
Grandma L. 0pets
Herb 1 pets
Mittens Jr cat
我們再次遇到了一個典型的n + 1查詢行爲示例。我們可以通過執行JOIN來避免這種情況。
彙總記錄
>>>subquery = Pet.select(fn.COUNT(Pet.id)).where(Pet.owner == Person.id).
>>>query = (Person
... .select(Person, Pet,subquery.alias(’pet_count’))
... .join(Pet,JOIN_LEFT_OUTER)
... .order_by(Person.name))
>>> forperson in query.aggregate_rows(): # Note the ‘aggregate_rows()‘ call.
... print person.name,person.pet_count, ’pets’
... for pet in person.pets:
... print ’ ’, pet.name, pet.animal_type
...
Bob 2 pets
Kitty cat
Fido dog
Grandma L. 0pets
Herb 1 pets
Mittens Jr cat
即使我們創建的查詢分開,只有一個查詢的實際執行。
最後,讓我們做一個複雜的例子。讓我們把所有的生日都找回來:
•1940歲之前(祖母)
•1959後(鮑勃)