peewee v0.3.2 documentation
Below are outlined some of the ways to perform typical database-related tasks with peewee.
Examples will use the following models:
import peewee
class Blog(peewee.Model):
creator = peewee.CharField()
name = peewee.CharField()
class Entry(peewee.Model):
blog = peewee.ForeignKeyField(Blog)
title = peewee.CharField()
body = peewee.TextField()
pub_date = peewee.DateTimeField()
published = peewee.BooleanField(default=True)
It is necessary to explicitly connect to the database before using it. By default, peewee provides a default database in the module-scope:
>>> peewee.database.connect()
>>> Blog.create_table()
>>> Entry.create_table()
It is possible to use multiple databases (provided that you don’t try and mix models from each):
>>> custom_db = peewee.SqliteDatabase('custom.db')
>>> class CustomModel(peewee.Model):
... whatev = peewee.CharField()
...
... class Meta:
... database = custom_db
...
>>> custom_db.connect()
>>> CustomModel.create_table()
Standard practice is to define a base model class that points at your custom database, and then all your models will extend it:
custom_db = peewee.SqliteDatabase('custom.db')
class CustomModel(peewee.Model):
class Meta:
database = custom_db
class Blog(CustomModel):
author = peewee.CharField()
name = peewee.TextField()
class Entry(CustomModel):
# etc, etc
You can use the create method on the model:
>>> Blog.create(creator='Charlie', name='My Blog')
<__main__.Blog object at 0x2529350>
Alternatively, you can build up a model instance programmatically and then save it:
>>> blog = Blog()
>>> blog.creator = 'Chuck'
>>> blog.name = 'Another blog'
>>> blog.save()
>>> blog.id
2
Once a model instance has a primary key, any attempt to re-save it will result in an update rather than another insert:
>>> blog.save()
>>> blog.id
2
>>> blog.save()
>>> blog.id
2
>>> Blog.get(id=1)
<__main__.Blog object at 0x25294d0>
>>> Blog.get(id=1).name
u'My Blog'
>>> Blog.get(creator='Chuck')
<__main__.Blog object at 0x2529410>
>>> Blog.get(creator='Chuck').name
u'Another blog'
To simply get all instances in a table, call the select method:
>>> for blog in Blog.select():
... print blog.name
...
My Blog
Another blog
To get all the related instances for an object, you can query the related name:
>>> for entry in blog.entry_set:
... print entry.title
...
entry 1
entry 2
entry 3
entry 4
>>> for entry in Entry.select().where(blog=blog, published=True):
... print '%s: %s (%s)' % (entry.blog.name, entry.title, entry.published)
...
My Blog: Some Entry (True)
My Blog: Another Entry (True)
>>> for entry in Entry.select().where(pub_date__lt=datetime.datetime(2011, 1, 1)):
... print entry.title, entry.pub_date
...
Old entry 2010-01-01 00:00:00
You can also filter across joins:
>>> for entry in Entry.select().join(Blog).where(name='My Blog'):
... print entry.title
Old entry
Some Entry
Another Entry
>>> for e in Entry.select().order_by('pub_date'):
... print e.pub_date
...
2010-01-01 00:00:00
2011-06-07 14:08:48
2011-06-07 14:12:57
>>> for e in Entry.select().order_by(peewee.desc('pub_date')):
... print e.pub_date
...
2011-06-07 14:12:57
2011-06-07 14:08:48
2010-01-01 00:00:00
You can also order across joins although its a little trickier. Assuming you want to order entries by the name of the blog, then by pubdate:
>>> qry = Entry.select().join(Blog).order_by('name').switch(Entry).order_by('pub_date')
>>> qry.sql()
('SELECT t1.* FROM entry AS t1 INNER JOIN blog AS t2 ON t1.blog_id = t2.id ORDER BY t2.name ASC, t1.pub_date ASC', [])
The strangeness there is that you need to join on Blog first so that it can be ordered on, then after specifying the ordering for Blog, switch back to Entry and order on it.
The paginate method makes it easy to grab a “page” or records – it takes two parameters, page_number, and items_per_page:
>>> for entry in Entry.select().order_by('id').paginate(2, 10):
... print entry.title
...
entry 10
entry 11
entry 12
entry 13
entry 14
entry 15
entry 16
entry 17
entry 18
entry 19
You can count the number of rows in any select query:
>>> Entry.select().count()
100
>>> Entry.select().where(id__gt=50).count()
50