這部分是query相關的筆記:python
peewee————查詢mysql
1.建立單條記錄(有多種方法):sql
準備:數據庫
>>> from peewee import *express
>>> db = MySQLDatabase('vmrecord',host='localhost',port=3306,user='root',password='root')安全
class test1(Model):dom
username = CharField()python2.7
class Meta:函數
database = dbatom
db.connect()
方法一:
>>> test1.create(username='hoci')
<__main__.test1 object at 0x7fdd1d637650>
方法二:
>>> user = test1(username='liso')
>>> user.save()
1
方法三:
>>> user1 = test1()
>>> user1.username = 'jack'
>>> user1.save()
1
若是model有外鍵,建立新記錄時能夠直接指定外鍵field:
>>> tweet = Tweet.create(user=huey, message='Hello!')
或引用其主鍵:
>>> tweet = Tweet.create(user=2, message='Hello again!')
(例子來自文檔)
方法四:
>>> test1.insert(username='michelle').execute()
4L #返回主鍵中的新行號數
2.建立多條記錄(批量插入):
最快的方法:
>>> data = [{'username':'sla'},{'username':'saf'},{'username':'djangs'}]
>>> data
[{'username': 'sla'}, {'username': 'saf'}, {'username': 'djangs'}]
>>> with db.atomic():
... test1.insert_many(data).execute()
...
True
若是你要手動遍歷data再執行insert,效率會慢得多,文檔舉的更慢例子:
較慢:
with db.atomic():
for data_dict in data_source:
Model.create(**data_dict)
更慢:
data_source = [
{'field1': 'val1-1', 'field2': 'val1-2'},
{'field1': 'val2-1', 'field2': 'val2-2'},
# ...
]
for data_dict in data_source:
Model.create(**data_dict)
若是數據的確比較大,能夠分段插入:
with db.atomic():
for idx in range(0, len(data_source), 1000):
Model.insert_many(data_source[idx:idx+1000]).execute()
也能夠引用其餘的數據插入:
query = (TweetArchive
.insert_from(
fields=[Tweet.user, Tweet.message],
query=Tweet.select(Tweet.user, Tweet.message))
.execute())
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
| 8 | djangs |
+----+----------+
3.更新記錄:
若是反覆執行某一個model實例的save方法,只會執行update,而不是insert
執行查詢更新:
先插入記錄:
>>> test1.insert(username='ka')
檢查:
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
| 8 | djangs |
| 9 | ka |
+----+----------+
更新id爲9的username:
>>> query = test1.update(username='kafla').where(test1.id == 9)
>>> query.execute()
1L
檢查:
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
| 8 | djangs |
| 9 | kafla |
+----+----------+
8 rows in set (0.00 sec)
官方例子:
>>> today = datetime.today()
>>> query = Tweet.update(is_published=True).where(Tweet.creation_date < today)
>>> query.execute() # Returns the number of rows that were updated.
4
其餘例子:
>>> query = Stat.update(counter=Stat.counter + 1).where(Stat.url == request.url)
>>> query.execute()
>>> query = Employee.update(bonus=(Employee.bonus + (Employee.salary * .1)))
>>> query.execute() # Give everyone a bonus!
使用子查詢與數據庫函數的例子:
>>> subquery = Tweet.select(fn.COUNT(Tweet.id)).where(Tweet.user == User.id)
>>> update = User.update(num_tweets=subquery)
>>> update.execute()
4.刪除記錄:
使用delete_instance():
>>> user = test1.get(test1.id == 9)
>>> user.delete_instance()
1L
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
| 8 | djangs |
+----+----------+
7 rows in set (0.00 sec)
或者用where配合delete:
>>> query = test1.delete().where(test1.username == 'djangs').execute()
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
+----+----------+
6 rows in set (0.00 sec)
5.獲取記錄:
使用get():
>>> test1.get(test1.id == 1)
<__main__.test1 object at 0x7f39baa03bd0>
>>> test1.get(test1.id == 1).username
u'hoci'
>>> test1.get(test1.id == 1).username
u'hoci'
>>> ob = test1.get(test1.username == 'jack')
>>> ob.username
u'jack'
>>> ob.id
3
若是試圖獲取一個不存在的值,會報錯:
>>> ob = test1.get(test1.username == 'shit')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 4012, in get
return sq.get()
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2645, in get
% self.sql())
peewee.test1DoesNotExist: Instance matching query does not exist:
SQL: SELECT `t1`.`id`, `t1`.`username` FROM `test1` AS t1 WHERE (`t1`.`username` = %s)
PARAMS: [u'shit']
你也能夠在查詢中調用get():
(官方例子)
>>> (Tweet
... .select()
... .join(User)
... .where(User.username == 'charlie')
... .order_by(Tweet.created_date.desc())
... .get())
<__main__.Tweet object at 0x2623410>
6.特殊操做:
Get or create:
使用get or create時,會返回一個2元組,第一個元素是實例,第二個是一個布爾值,表示是否建立新記錄:
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
+----+----------+
6 rows in set (0.00 sec)
>>> res = test1.get_or_create(username='jack')
>>> res
(<__main__.test1 object at 0x7f39baa03d50>, False)
>>> res[0].username
u'jack'
元組的第一個元素是該對象,第二個false表示沒有建立新記錄
建立新記錄:
>>> res = test1.get_or_create(username='newguy')
>>> res
(<__main__.test1 object at 0x7f39baa03c50>, True)
>>> res[0].username
'newguy'
>>> res[0].id
11L
建立了新記錄:
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1 | hoci |
| 2 | liso |
| 3 | jack |
| 4 | michelle |
| 6 | sla |
| 7 | saf |
| 11 | newguy |
+----+----------+
7 rows in set (0.00 sec)
其餘內容的關鍵字與概要:
Selecting multiple records
(Model.select())
Filtering records
(使用比較大小相似的方式過濾)
More query examples
(例子)
Sorting records
(升降序可選)
Getting random records
(mysql使用fn.Rand()獲取隨機記錄)
Paginating records
(實現記錄分頁)
Counting records
Aggregating records
(統計聚合)
SQL Functions, Subqueries and 「Raw expressions」
(使用SQL表達式)
Security and SQL Injection
(有關安全與SQL注入)
Retrieving raw tuples / dictionaries
(以字典或元組的形式獲取記錄,配合group_by()用)
使用數據庫函數的例子(用fn.FUNCTION調用):
A lot of fun things can go in the where clause of a query, such as:
A field expression, e.g. User.username == 'Charlie'
A function expression, e.g. fn.Lower(fn.Substr(User.username, 1, 1)) == 'a'
A comparison of one column to another, e.g. Employee.salary < (Employee.tenure * 1000) + 40000
You can also nest queries, for example tweets by users whose username starts with 「a」:
# get users whose username starts with "a"
a_users = User.select().where(fn.Lower(fn.Substr(User.username, 1, 1)) == 'a')
# the "<<" operator signifies an "IN" query
a_user_tweets = Tweet.select().where(Tweet.user << a_users)