Peewee簡介
Peewee是一個簡單小巧的Python ORM(對象關系映射 Object Relational Mapping,簡稱ORM),支持SQLite、MySQL、PostgreSQL等數據庫,本文主講前兩者。
創建MySQL數據庫
- 去官網下載MySQL並啟動mysql服務;
- 打開MySQL Workbench配置好數據庫,如密碼等;
- 在PyCharm中用Peewee創建數據庫,如db_model.py;
from peewee import *
# test為數據庫名,並需安裝mysql庫
db = MySQLDatabase("test", **{'charset': 'utf8', 'use_unicode': True, 'host': 'localhost', 'user': 'root', 'password': '***'})
# 基類
class BaseModel(Model):
class Meta:
database = db
# 表類
class Test(BaseModel):
id = IntegerField(primary_key=True)
name = CharField()
gender = CharField()
class Meta:
# 表名
table_name = 'Test'
# 創建表
def create_table(table):
if not table.table_exists():
table.create_table()
# 刪除表
def drop_table(table):
if table.table_exists():
table.drop_table()
# 創建一張Test表
create_table(Test)
- 再打開MySQL Workbench就可以看到剛剛創建的Test數據庫和Test表;
創建SQLite數據庫
- SQLite數據庫可以直接由Peewee創建,與上db_model.py類似,修改創建語句即可;
# 數據庫文件路徑
db_path = "../database/test.db"
db = SqliteDatabase(db_path)
# PostgreSQL數據庫則調用PostgresqlDatabase方法即可
# db = PostgresqlDatabase('test', user='postgres')
創建完畢可以通過PyCharm自帶的Database查看數據庫,也可以使用其它軟件查看
- 本想通過DBeaver打開db文件(包括連接MySQL數據庫),方便后續操作,嘗試半天發現可以連接但是怎么都無法顯示,不知道是否與版本問題有關(這里嘗試的是21.0.3版本),后來使用了JetBrains DataGrip(據說很好用),成功打開db文件(也可以使用SQLite Studio)
Peewee操作數據庫
列舉常用操作,即增刪改查,其它操作后續慢慢補充
新增
t = Tset(name="test", gender="男")
t.save()
# 或者
t = Test()
t.name = "test"
t.gender = "男"
t.save()
# insert() 只插入數據,不返回對象實例
Test.insert(name="test", gender="男").excute()
# insert_many() 插入多行,rows為元組或字典列表,fields為需要插入的字段名list列表
rows = [
{"name": "test1", "gender": "男"},
{"name": "test2", "gender": "女"}
]
insert_many(rows, fields=None).execute()
# 或
rows = [
{"test1", "男"},
{"test2", "女"}
]
fields = ["name", "gender"]
insert_many(rows, fields=fields).execute()
刪除
# where()是條件,execute()是執行
Test.delete().where(Test.name == "test").execute()
# 已經實例化的數據, 使用delete_instance()
t = Tset(name="test", gender="男").save()
t.delete_instance()
查詢
找到了會返回model實例,未找到會拋出異常DoesNotExist
# 查詢單條數據,多條件用逗號或邏輯運算符隔開,也支持其它比較符(大於小於等)
t = Test.get(Test.name == "test")
# 使用where().get()查詢
t = Test.select().where(Test.name == "test").get()
# 查詢多條數據
tests = Test.select().where(Test.gender == "男")
# 迭代結果
for t in tests:
t.save()
# in操作
tests = Test.select().where(Test.gender.in_(["男"]))
# 通過id獲取
t = Test.get_by_id(1)
# 嘗試獲取,不存在則創建,t為實例,created為是否創建
# 參數name為自定義查詢條件,dafaults並非查詢條件,而是創建字段
t, created = Test.get_or_create(name="test", defaults={"gender": "男"})
# {"gender": "男"}也可以寫作dict(gender="男")
# 查詢結果轉字典dicts
t = Test.select().dicts()
# 只返回元組迭代器tuples
t = Test.select().tuples()
查詢條件支持的比較符和運算符
符號 | 含義 |
---|---|
& | 與 |
| | 或 |
~ | 非 |
== | 等於 |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
!= | 不等於 |
<< | x in y,其中 y 是列表或查詢 |
>> | x is y,其中 y 可以是 None |
% | x like y,where(Test.name % "a*")區分大小寫 |
** | x like y,where(Test.name ** "a%")不區分大小寫 |
其它查詢條件,如
tests = Test.select().where(Test.name.contains("t"))
.in_(value) IN查找(與相同<<)。
.not_in(value) 不在查詢中。
.is_null(is_null) 是NULL還是IS NOT NULL。接受布爾參數。
.contains(substr) 通配符搜索子字符串。
.startswith(prefix) 搜索以開頭的值prefix。
.endswith(suffix) 搜索以結尾的值suffix。
.between(low, high) 在low和之間搜索值high。
.regexp(exp) 正則表達式匹配(區分大小寫)。
.iregexp(exp) 正則表達式匹配(不區分大小寫)。
.bin_and(value) 二進制AND。
.bin_or(value) 二進制或。
.concat(other) 使用串聯兩個字符串或對象||。
.distinct() 標記列以進行DISTINCT選擇。
.collate(collation) 用給定的排序規則指定列。
.cast(type) 將列的值強制轉換為給定的類型。
修改
# 已經實例化的數據,直接修改對象屬性並save()
t = Tset(name="test", gender="男").save()
t.gender = "女"
t.save()
# 查詢后並用update()更新
t = Tset.update({Tset.gender: "女"}).where(Person.name == "test")
t.execute()
# 查詢出對象並修改屬性
t = Test.get(Test.name == 'test')
t.gender = "女"
t.save()
其它
# 使用order_by()進行排序,多個字段用分號隔開
tests = Test.select().order_by(Test.id)
# 升序(默認)
tests = Test.select().order_by(Test.id.asc())
tests = Test.select().order_by(+Test.id)
# 降序
tests = Test.select().order_by(Test.id.desc())
tests = Test.select().order_by(-Test.id)
# 使用count()進行統計
n = Test.select().count()
# 執行原生語句
name = "test"
gender = "男"
Test.raw('SELECT * FROM test WHERE name= %s and gender = %s', name, gender)
# fn操作
# 1.Avg 平均值
# 2.Sum 和
# 3.Max 最大值
# 4.Min 最小值
# 5.Count 合計
# 6.Substr 切片
t= Test.select(fn.MAX(Test.id))
補充
創建表格時的常用類型
AutoField:integer
JsonField: 8字節
MediumJSONField: 16字節
UUIDField:varchar(40)
CharField:varchar
IntegerField:integer
DecimalField:numeric
TextField:text
DateTimeField:datetime
DateField:date
TimeField:time
FixedCharField:char
BigAutoField:bigint
BigIntegerField:bigint
SmallIntegerField:smallint
IdentityField:not supported
FloatField:real
DoubleField:double precision
BlobField:blob
BitField:bigint
BigBitField:blob
BinaryUUIDField:varbinary(16)
TimestampField:integer
IPField:bigint
BooleanField:bool
BareField:not supported
ForeignKeyField:integer
ManyToManyField:無
創建表格時的常用字段
null = False 是否允許空字符串。
index = False 是否創建普通索引。
unique = False 是否創建唯一索引。
column_name = None 在數據庫中指定列的名稱,一般不設置會使用定義model時的變量名作為列名。
default = None 設置默認值。
primary_key = False 是否為主鍵。
constraints = None 增加約束,如果增加,該值是一個列表。
collation = None 用於排序字段或索引的排序規則。
choices = None 設置可選的枚舉選項,值是一個元組,元素也是一個元組,例如((1,‘女’),(2,‘男’))。
help_text = None 設置備注或注釋文本。
verbose_name = None 設置一個可讀性良好的名稱,例如 name = CharField(verbose_name = ‘用戶名’)。
index_type = None 指定索引類型,不常用,一般默認即可。