这部分是query相关的笔记:
peewee————查询
1.创建单条记录(有多种方法):
准备:
>>> from peewee import *
>>> db = MySQLDatabase(‘vmrecord‘,host=‘localhost‘,port=3306,user=‘root‘,password=‘root‘)
class test1(Model):
username = CharField()
class Meta:
database = db
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)