Peewee Tutorial
Peewee Tutorial
i
Peewee
Audience
This tutorial is for all those programmers who wish to learn in detail about the basics and
the functions of Peewee which is an expressive object relational mapper (ORM)
implemented in joining the relational data with python objects.
Prerequisites
We assume that the readers of this tutorial have basic knowledge of Python, Object
Relational Mapping (ORM) and databases like SQLite, MySQL, etc.
All the content and graphics published in this e-book are the property of Tutorials Point (I)
Pvt. Ltd. The user of this e-book is prohibited to reuse, retain, copy, distribute or republish
any contents or a part of contents of this e-book in any manner without written consent
of the publisher.
We strive to update the contents of our website and tutorials as timely and as precisely as
possible, however, the contents may contain inaccuracies or errors. Tutorials Point (I) Pvt.
Ltd. provides no guarantee regarding the accuracy, timeliness or completeness of our
website or its contents including this tutorial. If you discover any errors on our website or
in this tutorial, please notify us at [email protected]
i
Peewee
Table of Contents
About the Tutorial ............................................................................................................................................ i
Audience ........................................................................................................................................................... i
Prerequisites ..................................................................................................................................................... i
3. Peewee — Model...................................................................................................................................... 4
ForeignKeyField ............................................................................................................................................... 7
Alternatives ................................................................................................................................................... 16
ii
Peewee
Tables ............................................................................................................................................................ 35
iv
1. Peewee – Overview Peewee
Peewee is a Python Object Relational Mapping (ORM) library which was developed by a
U.S. based software engineer Charles Leifer in October 2010. Its latest version is 3.13.3.
Peewee supports SQLite, MySQL, PostgreSQL and Cockroach databases.
On the other hand, databases like Oracle, MySQL, SQLite and others can only store and
manipulate scalar values such as integers and strings organised within tables.
The programmer must either convert the object values into groups of scalar data types
for storage in the database or convert them back upon retrieval, or only use simple scalar
values within the program.
In an ORM system, each class maps to a table in the underlying database. Instead of
writing tedious database interfacing code yourself, an ORM takes care of these issues,
while you can focus on programming the logics of the system.
Environment setup
To install latest version of Peewee as hosted on PyPI (Python Package Index), use pip
installer.
There are no other dependencies for Peewee to work. It works with SQLite without
installing any other package as sqlite3 module is bundled with standard library.
However, to work with MySQL and PostgreSQL, you may have to install DB-API compatible
driver modules pymysql and pyscopg2 respectively. Cockroach database is handled
through playhouse extension that is installed by default along with Peewee.
1
2. Peewee — Database Class Peewee
Database class instance has all the information required to open connection with database
engine, and is used to execute queries, manage transactions and perform introspection of
tables, columns, etc.
Here, pragma is SQLite extension which is used to modify operation of SQLite library.
This parameter is either a dictionary or a list of 2-tuples containing pragma key and value
to set every time a connection is opened.
Timeout parameter is specified in seconds to set busy-timeout of SQLite driver. Both the
parameters are optional.
Following statement creates a connection with a new SQLite database (if it doesn’t exist
already).
>>> db = peewee.SqliteDatabase('mydatabase.db')
Pragma parameters are generally given for a new database connection. Typical attributes
mentioned in pragmase dictionary are journal_mode, cache_size, locking_mode,
foreign-keys, etc.
1 enforce foreign-key
foreign_keys constraints
Peewee also has Another Python SQLite Wrapper (apsw), an advanced sqlite driver. It
provides advanced features such as virtual tables and file systems, and shared
connections. APSW is faster than the standard library sqlite3 module.
3
3. Peewee — Model Peewee
An object of Model sub class in Peewee API corresponds to a table in the database with
which connection has been established. It allows performing database table operations
with the help of methods defined in the Model class.
A user defined Model has one or more class attributes, each of them is an object of Field
class. Peewee has a number of subclasses for holding data of different types. Examples
are TextField, DatetimeField, etc. They correspond to the fields or columns in the database
table. Reference of associated database and table and model configuration is mentioned
in Meta class. Following attributes are used to specify configuration:
Attribute Description
db_table Name of the table to store data. By default, it is name of model class.
without_rowid Indicate that table should not have rowid (SQLite only).
database=db
db_table='User'
4
Peewee
User.create_table()
User.create_table()
rec1=User(name="Rajesh", age=21)
rec1.save()
Classmethod alias() Create an alias to the model-class. It allows the same Model
to any referred multiple times in a query.
classmethod get() Retrieve a single row from mapped table matching the given
filters.
5
4. Peewee — Field Class Peewee
Model class contains one or more attributes that are objects of Field class in Peewee. Base
Field class is not directly instantiated. Peewee defines different sub classes for equivalent
SQL data types.
Subclasses of Field class are mapped to corresponding data types in various databases,
i.e. SQLite, PostgreSQL, MySQL, etc.
6
Peewee
Text fields
The text fields which are available in Peewee are as follows:
CharField Field class for storing strings. Max 255 characters. Equivalent SQL
data type is varchar.
Binary fields
The binary fields in Peewee are explained below:
Since SQLite doesn’t have DateTime data types, this field is mapped as string.
ForeignKeyField
This class is used to establish foreign key relationship in two models and hence, the
respective tables in database. This class in instantiated with following parameters:
backref (str) Accessor name for back-reference. “+” disables the back-reference
accessor.
7
Peewee
lazy_load (bool) Fetch the related object, when the foreign-key field attribute is
accessed. If FALSE, accessing the foreign-key field will return the value
stored in the foreign-key column.
Example
Here is an example of ForeignKeyField.
db = SqliteDatabase('mydatabase.db')
class Customer(Model):
id=IntegerField(primary_key=True)
name = TextField()
address = TextField()
phone = IntegerField()
class Meta:
database=db
db_table='Customers'
class Invoice(Model):
id=IntegerField(primary_key=True)
invno=IntegerField()
amount=IntegerField()
custid=ForeignKeyField(Customer, backref='Invoices')
class Meta:
database=db
db_table='Invoices'
db.create_tables([Customer, Invoice])
8
Peewee
custid_id
)
REFERENCES Customers (id)
);
When verified in SQLiteStuidio GUI tool, the table structure appears as below:
9
Peewee
IPField Field class for storing IPv4 addresses efficiently (as integers).
IdentityField Field class for storing auto-incrementing primary keys using the new
Postgres 10 IDENTITY column type.
10
5. Peewee — Insert a New Record Peewee
In Peewee, there are more than one commands by which, it is possible to add a new record
in the table. We have already used save() method of Model instance.
rec1=User(name="Rajesh", age=21)
rec1.save()
The Peewee.Model class also has a create() method that creates a new instance and add
its data in the table.
User.create(name="Kiran", age=19)
In addition to this, Model also has insert() as class method that constructs SQL insert
query object. The execute() method of Query object performs adding a row in underlying
table.
q = User.insert(name='Lata', age=20)
q.execute()
The query object is an equivalent INSERT query.q.sql() returns the query string.
print (q.sql())
('INSERT INTO "User" ("name", "age") VALUES (?, ?)', ['Lata', 20])
Here is the complete code that demonstrates the use of above ways of inserting record.
db.create_tables([User])
rec1=User(name="Rajesh", age=21)
rec1.save()
a=User(name="Amar", age=20)
11
Peewee
a.save()
User.create(name="Kiran", age=19)
q = User.insert(name='Lata', age=20)
q.execute()
db.close()
Bulk Inserts
In order to use multiple rows at once in the table, Peewee provides two methods:
bulk_create and insert_many.
insert_many()
The insert_many() method generates equivalent INSERT query, using list of dictionary
objects, each having field value pairs of one object.
Here too, q.sql() returns the INSERT query string is obtained as below:
print (q.sql())
('INSERT INTO "User" ("name", "age") VALUES (?, ?), (?, ?)', ['Rajesh', 21,
'Amar', 20])
12
Peewee
bulk_create()
This method takes a list argument that contains one or more unsaved instances of the
model mapped to a table.
a=User(name="Kiran", age=19)
b=User(name='Lata', age=20)
User.bulk_create([a,b])
db.create_tables([User])
rows=[{"name":"Rajesh", "age":21}, {"name":"Amar", "age":20}]
q=User.insert_many(rows)
q.execute()
a=User(name="Kiran", age=19)
b=User(name='Lata', age=20)
User.bulk_create([a,b])
db.close()
13
6. Peewee — Select Records Peewee
Simplest and the most obvious way to retrieve data from tables is to call select() method
of corresponding model. Inside select() method, we can specify one or more field
attributes. However, if none is specified, all columns are selected.
14
7. Peewee — Filters Peewee
It is possible to retrieve data from SQLite table by using where clause. Peewee supports
following list of logical operators.
== x equals y
< x is less than y
<= x is less than or equal to y
> x is greater than y
>= x is greater than or equal to y
!= x is not equal to y
<< x IN y, where y is a list or query
>> x IS y, where y is None/NULL
% x LIKE y where y may contain wildcards
** x ILIKE y where y may contain wildcards
^ x XOR y
~ Unary negation (e.g., NOT x)
rows=User.select().where (User.age>=20)
for row in rows:
print ("name: {} age: {}".format(row.name, row.age))
Following code displays only those name present in the names list.
15
Peewee
Filtering Methods
In addition to the above logical operators as defined in core Python, Peewee provides
following methods for filtering:
As an example of above methods, look at the following code. It retrieves names starting
with ‘R’ or ending with ‘r’.
Alternatives
Python’s built-in operators in, not in, and, or etc. will not work. Instead, use Peewee
alternatives.
16
Peewee
| instead of or.
~ instead of not.
.is_null() instead of is.
None or == None.
17
8. Peewee — Primary and Composite Keys Peewee
It is recommended that the table in a relational database, should have one of the columns
applied with primary key constraint. Accordingly, Peewee Model class can also specify field
attribute with primary-key argument set to True. However, if model class doesn’t have
any primary key, Peewee automatically creates one with the name “id”. Note that the User
model defined above doesn’t have any field explicitly defined as primary key. Hence, the
mapped User table in our database has an id field.
To define an auto-incrementing integer primary key, use AutoField object as one attribute
in the model.
You can also assign any non-integer field as a primary key by setting primary_key
parameter to True. Let us say we want to store certain alphanumeric value as user_id.
18
Peewee
However, when model contains non-integer field as primary key, the save() method of
model instance doesn’t cause database driver to generate new ID automatically, hence we
need to pass force_insert=True parameter. However, note that the create() method
implicitly specifies force_insert parameter.
User.create(user_id='A001',name="Rajesh", age=21)
b=User(user_id='A002',name="Amar", age=20)
b.save(force_insert=True)
The save() method also updates an existing row in the table, at which time, force_insert
primary is not necessary, as ID with unique primary key is already existing.
Peewee allows feature of defining composite primary key. Object of CompositeKey class
is defined as primary key in Meta class. In following example, a composite key consisting
of name and city fields of User model has been assigned as composite key.
If you wish, the table should not have a primary key, then specify primary_key=False in
model’s Meta class.
19
9. Peewee — Update Existing Records Peewee
Existing data can be modified by calling save() method on model instance as well as with
update() class method.
Following example fetches a row from User table with the help of get() method and
updates it by changing the value of age field.
row=User.get(User.name=="Amar")
print ("name: {} age: {}".format(row.name, row.age))
row.age=25
row.save()
The update() method of Method class generates UPDATE query. The query object’s
execute() method is then invoked.
Following example uses update() method to change the age column of rows in which it is
>20.
qry=User.update({User.age:25}).where(User.age>20)
print (qry.sql())
qry.execute()
('UPDATE "User" SET "age" = ? WHERE ("User"."age" > ?)', [25, 20])
Peewee also has a bulk_update() method to help update multiple model instance in a
single query operation. The method requires model objects to be updated and list of fields
to be updated.
Following example updates the age field of specified rows by new value.
rows=User.select()
rows[0].age=25
rows[2].age=23
User.bulk_update([rows[0], rows[2]], fields=[User.age])
20
10. Peewee — Delete Records Peewee
obj=User.get(User.name=="Amar")
obj.delete_instance()
On the other hand, delete() is a class method defined in model class, which generates
DELETE query. Executing it effectively deletes rows from the table.
db.create_tables([User])
qry=User.delete().where (User.age==25)
qry.execute()
21
11. Peewee — Create Index Peewee
By using Peewee ORM, it is possible to define a model which will create a table with index
on single column as well as multiple columns.
As per the Field attribute definition, setting unique constraint to True will create an index
on the mapped field. Similarly, passing index=True parameter to field constructor also
create index on the specified field.
In following example, we have two fields in MyUser model, with username field having
unique parameter set to True and email field has index=True.
class MyUser(Model):
username = CharField(unique=True)
email = CharField(index=True)
class Meta:
database=db
db_table='MyUser'
As a result, SQLiteStudio graphical user interface (GUI) shows indexes created as follows:
In order to define a multi-column index, we need to add indexes attribute in Meta class
inside definition of our model class. It is a tuple of 2-item tuples, one tuple for one index
definition. Inside each 2-element tuple, the first part of which is a tuple of the names of
the fields, the second part is set to True to make it unique, and otherwise is False.
name=TextField()
city=TextField()
22
Peewee
age=IntegerField()
class Meta:
database=db
db_table='MyUser'
indexes=(
(('name', 'city'), True),
)
You can also create index by manually providing SQL helper statement as parameter to
add_index() method.
Above method is particularly required when using SQLite. For MySQL and PostgreSQL, we
can obtain Index object and use it with add_index() method.
ind=MyUser.index(MyUser.name)
MyUser.add_index(ind)
23
12. Peewee — Constraints Peewee
Constraints are restrictions imposed on the possible values that can be put in a field. One
such constraint is primary key. When primary_key=True is specified in Field definition,
each row can only store unique value – same value of the field cannot be repeated in
another row.
If a field is not a primary key, still it can be constrained to store unique values in table.
Field constructor also has constraints parameter.
MyUser.create(name="Rajesh", city="Mumbai",age=9)
peewee.IntegrityError: CHECK constraint failed: MyUser
In the field definition, we can also use DEFAULT constraint as in following definition of
city field.
city=TextField(constraints=[SQL("DEFAULT 'Mumbai'")])
24
Peewee
So, the model object can be constructed with or without explicit value of city. If not used,
city field will be filled by default value – Mumbai.
25
13. Peewee — Using MySQL Peewee
First, you should have MySQL server installed in your machine. It can be a standalone
MySQL server installed from https://dev.mysql.com/downloads/installer/.
You can also work on Apache bundled with MySQL (such as XAMPP downloaded and
installed from https://www.apachefriends.org/download.html ).
The create a new database named mydatabase. We shall use phpmyadmin interface
available in XAMPP.
import pymysql
26
Peewee
Once a database is created on the server, we can now declare a model and thereby, create
a mapped table in it.
The MySQLDatabase object requires server credentials such as host, port, user name and
password.
db.connect()
db.create_tables([MyUser])
27
14. Peewee — Using PostgreSQL Peewee
Peewee supports PostgreSQL database as well. It has PostgresqlDatabase class for that
purpose. In this chapter, we shall see how we can connect to Postgres database and create
a table in it, with the help of Peewee model.
As in case of MySQL, it is not possible to create database on Postgres server with Peewee’s
functionality. The database has to be created manually using Postgres shell or PgAdmin
tool.
First, we need to install Postgres server. For windows OS, we can download
https://get.enterprisedb.com/postgresql/postgresql-13.1-1-windows-x64.exe and install.
Next, install Python driver for Postgres – Psycopg2 package using pip installer.
Then start the server, either from PgAdmin tool or psql shell. We are now in a position to
create a database. Run following Python script to create mydatabase on Postgres server.
import psycopg2
Check that the database is created. In psql shell, it can be verified with \l command:
To declare MyUser model and create a table of same name in above database, run following
Python code:
28
Peewee
city=TextField(constraints=[SQL("DEFAULT 'Mumbai'")])
age=IntegerField()
class Meta:
database=db
db_table='MyUser'
db.connect()
db.create_tables([MyUser])
We can verify that table is created. Inside the shell, connect to mydatabase and get list of
tables in it.
To check structure of newly created MyUser database, run following query in the shell.
29
15. Peewee — Defining Database Dynamically Peewee
db.connect()
db.create_tables([MyUser])
You can also associate models to any database object during run-time using bind()
method declared in both database class and model class.
30
Peewee
31
16. Peewee — Connection Management Peewee
Database object is created with autoconnect parameter set as True by default. Instead,
to manage database connection programmatically, it is initially set to False.
db=SqliteDatabase("mydatabase", autoconnect=False)
The database class has connect() method that establishes connection with the database
present on the server.
db.connect()
db.close()
>>> db.connect()
True
>>> db.connect()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\peewee\lib\site-packages\peewee.py", line 3031, in connect
raise OperationalError('Connection already opened.')
peewee.OperationalError: Connection already opened.
>>> db.connect(reuse_if_open=True)
False
Calling close() on already closed connection won’t result error. You can however, check
if the connection is already closed with is_closed() method.
>>> if db.is_closed()==True:
db.connect()
True
>>>
Instead of explicitly calling db.close() in the end, it is also possible to use database object
as context_manager.
32
Peewee
db = SqliteDatabase('mydatabase.db', autoconnect=False)
33
17. Peewee — Relationships and Joins Peewee
Peewee supports implementing different type of SQL JOIN queries. Its Model class has a
join() method that returns a Join instance.
The joins table mapped with M1 model to that of m2 model and returns Join class instance.
The on parameter is None by default and is expression to use as join predicate.
Join Types
Peewee supports following Join types (Default is INNER).
JOIN.INNER
JOIN.LEFT_OUTER
JOIN.RIGHT_OUTER
JOIN.FULL
JOIN.FULL_OUTER
JOIN.CROSS
db = SqliteDatabase('mydatabase.db')
class BaseModel(Model):
class Meta:
database = db
class Item(BaseModel):
itemname = TextField()
price = IntegerField()
class Brand(BaseModel):
brandname = TextField()
item = ForeignKeyField(Item, backref='brands')
class Bill(BaseModel):
item = ForeignKeyField(Item, backref='bills')
34
Peewee
Tables
Next, we populate these tables with following test data:
Item Table
The item table is given below:
Brand Table
Given below is the brand table:
Bill Table
The bill table is as follows:
35
Peewee
To perform a simple join operation between Brand and Item tables, execute the following
code:
qs=Brand.select().join(Item)
for q in qs:
print ("Brand ID:{} Item Name: {} Price: {}".format(q.id, q.brandname,
q.item.price))
qs=Bill.select().join(Brand).join(Item)
for q in qs:
print ("BillNo:{} Brand:{} Item:{} price:{} Quantity:{}".format(q.id, \
q.brand.brandname, q.item.itemname, q.item.price, q.qty))
36
18. Peewee — Subqueries Peewee
db = SqliteDatabase('mydatabase.db')
class BaseModel(Model):
class Meta:
database = db
class Contacts(BaseModel):
RollNo = IntegerField()
Name = TextField()
City = TextField()
class Branches(BaseModel):
RollNo = IntegerField()
Faculty = TextField()
db.create_tables([Contacts, Branches])
After tables are created, they are populated with following sample data:
Contacts table
The contacts table is given below:
37
Peewee
In order to display name and city from contact table only for RollNo registered for ETC
faculty, following code generates a SELECT query with another SELECT query in its WHERE
clause.
db.close()
RollNo:104 City:Nasik
RollNo:108 City:Delhi
RollNo:110 City:Nasik
39
19. Peewee — Sorting Peewee
It is possible to select records from a table using order_by clause along with model’s
select() method. Additionally, by attaching desc() to the field attribute on which sorting
is to be performed, records will be collected in descending order.
Following code display records from contact table in ascending order of City names.
rows=Contacts.select().order_by(Contacts.City)
print ("Contact list in order of city")
for row in rows:
print ("RollNo:{} Name: {} City:{}".format(row.RollNo,row.Name, row.City))
Here is the sorted list which is arranged according to ascending order of city name.
rows=Contacts.select().order_by(Contacts.Name.desc())
print ("Contact list in descending order of Name")
for row in rows:
print ("RollNo:{} Name: {} City:{}".format(row.RollNo,row.Name, row.City))
40
Peewee
41
20. Peewee — Counting and Aggregation Peewee
We can find number of records reported in any SELECT query by attaching count()
method. For example, following statement returns number of rows in Contacts table with
City=’Nasik’.
qry=Contacts.select().where (Contacts.City=='Nasik').count()
print (qry)
SQL has GROUP BY clause in SELECT query. Peewee supports it in the form of
group_by() method. Following code returns city wise count of names in Contacts table.
db = SqliteDatabase('mydatabase.db')
class Contacts(BaseModel):
RollNo = IntegerField()
Name = TextField()
City = TextField()
class Meta:
database = db
db.create_tables([Contacts])
qry=Contacts.select(Contacts.City,
fn.Count(Contacts.City).alias('count')).group_by(Contacts.City)
print (qry.sql())
for q in qry:
print (q.City, q.count)
Chennai 1
Delhi 2
Indore 1
42
Peewee
Mumbai 1
Nagpur 1
Nasik 3
Pune 1
43
21. Peewee — SQL Functions Peewee
American National Standards Institute (ANSI) Structured Query Language (SQL) standard
defines many SQL functions.
In order to implement these SQL functions, Peewee has a SQL helper function fn(). In
above example, we used it to find count of records for each city.
Using Bill and Item tables from models defined earlier, we shall display sum of quantity of
each item as entered in Bill table.
Item table
The item table with the data is given below:
Bill table
The bill table is as follows:
We create a join between Bill and Item table, select item name from Item table and sum
of quantity from Bill table.
44
Peewee
db = SqliteDatabase('mydatabase.db')
class BaseModel(Model):
class Meta:
database = db
class Item(BaseModel):
itemname = TextField()
price = IntegerField()
class Brand(BaseModel):
brandname = TextField()
item = ForeignKeyField(Item, backref='brands')
class Bill(BaseModel):
item = ForeignKeyField(Item, backref='bills')
brand = ForeignKeyField(Brand, backref='bills')
qty = DecimalField()
qs=Bill.select(Item.itemname,
fn.SUM(Bill.qty).alias('Sum')).join(Item).group_by(Item.itemname)
print (qs)
for q in qs:
print ("Item: {} sum: {}".format(q.item.itemname, q.Sum))
db.close()
46
22. Peewee — Retrieving Row Peewee
Tuples/Dictionaries
It is possible to iterate over the resultset without creating model instances. This may be
achieved by using the following:
tuples() method.
dicts() method.
To return data of fields in SELECT query as collection of tuples, use tuples() method.
qry=Contacts.select(Contacts.City,
fn.Count(Contacts.City).alias('count')).group_by(Contacts.City).tuples()
lst=[]
for q in qry:
lst.append(q)
print (lst)
[('Chennai', 1), ('Delhi', 2), ('Indore', 1), ('Mumbai', 1), ('Nagpur', 1),
('Nasik', 3), ('Pune', 1)]
qs=Brand.select().join(Item).dicts()
lst=[]
for q in qs:
lst.append(q)
print (lst)
47
23. Peewee — User defined Operators Peewee
Peewee has Expression class with the help of which we can add any customized operator
in Peewee’s list of operators. Constructor for Expression requires three arguments, left
operand, operator and right operand.
Using Expression class, we define a mod() function that accepts arguments for left and
right and ‘%’ as operator.
We can use it in a SELECT query to obtain list of records in Contacts table with even id.
class BaseModel(Model):
class Meta:
database = db
class Contacts(BaseModel):
RollNo = IntegerField()
Name = TextField()
City = TextField()
db.create_tables([Contacts])
48
Peewee
for q in qry:
print (q.id, q.Name, q.City)
This code will emit following SQL query represented by the string:
2 Amar Delhi
4 Leena Nasik
6 Hema Nagpur
8 John Delhi
10 Raja Nasik
49
24. Peewee — Atomic Transactions Peewee
Peewee’s database class has atomic() method that creates a context manager. It starts
a new transaction. Inside the context block, it is possible to commit or rollback the
transaction depending upon whether it has been successfully done or it encountered
exception.
@db.atomic()
def create_user(nm,n):
return User.create(name=nm, age=n)
create_user('Amar', 20)
50
25. Peewee — Database Errors Peewee
Python’s DB-API standard (recommended by PEP 249) specifies the types of Exception
classes to be defined by any DB-API compliant module (such as pymysql, pyscopg2, etc.).
DatabaseError
DataError
IntegrityError
InterfaceError
InternalError
NotSupportedError
OperationalError
ProgrammingError
Instead of DB-API specific exceptions to be tried, we can implement above ones from
Peewee.
51
26. Peewee — Query Builder Peewee
Peewee also provides a non-ORM API to access the databases. Instead of defining models
and fields, we can bind the database tables and columns to Table and Column objects
defined in Peewee and execute queries with their help.
To begin with, declare a Table object corresponding to the one in our database. You have
to specify table name and list of columns. Optionally, a primary key can also be provided.
This table object is bound with the database with bind() method.
Contacts=Contacts.bind(db)
Now, we can set up a SELECT query on this table object with select() method and iterate
over the resultset as follows:
names=Contacts.select()
for name in names:
print (name)
Tuples
The program is as follows:
names=Contacts.select().tuples()
for name in names:
52
Peewee
print (name)
Namedtuples
The program is stated below:
names=Contacts.select().namedtuples()
for name in names:
print (name)
53
Peewee
Or
Contacts.insert(Records).execute()
The Peewee Table object has update() method to implement SQL UPDATE query. To
change City for all records from Nasik to Nagar, we use following query.
Contacts.update(City='Nagar').where((Contacts.City=='Nasik')).execute()
Finally, Table class in Peewee also has delete() method to implement DELETE query in
SQL.
Contacts.delete().where(Contacts.Name=='Abdul').execute()
54
27. Peewee — Integration with Web Frameworks Peewee
Peewee can work seamlessly with most of the Python web framework APIs. Whenever the
Web Server Gateway Interface (WSGI) server receives a connection request from client,
the connection with database is established, and then the connection is closed upon
delivering a response.
db = SqliteDatabase('mydatabase.db')
app = Flask(__name__)
@app.before_request
def _db_connect():
db.connect()
@app.teardown_request
def _db_close(exc):
if not db.is_closed():
db.close()
Peewee API can also be used in Django. To do so, add a middleware in Django app.
def PeeweeConnectionMiddleware(get_response):
def middleware(request):
db.connect()
try:
response = get_response(request)
finally:
if not db.is_closed():
db.close()
return response
return middleware
# settings.py
MIDDLEWARE_CLASSES = (
# Our custom middleware appears first in the list.
'my_blog.middleware.PeeweeConnectionMiddleware',
#followed by default middleware list.
..
)
Peewee can be comfortably used with other frameworks such as Bottle, Pyramid and
Tornado, etc.
56
28. Peewee — SQLite Extensions Peewee
Full-text search.
JavaScript Object Notation (JSON) extension integration.
Closure table extension support.
LSM1 extension support.
User-defined table functions.
Support for online backups using backup API: backup_to_file().
BLOB API support, for efficient binary data storage.
JSON data can be stored, if a special JSONField is declared as one of the field attributes.
class MyModel(Model):
json_data = JSONField(json_dumps=my_json_dumps)
To activate full-text search, the model can have DocIdField to define primary key.
class NoteIndex(FTSModel):
docid = DocIDField()
content = SearchField()
class Meta:
database = db
57
Peewee
On the other hand, playhouse.apsw module carries support for apsw sqlite driver. Another
Python SQLite Wrapper (APSW) is fast and can handle nested transactions, that are
managed explicitly by you code.
db = APSWDatabase('testdb')
class BaseModel(Model):
class Meta:
database = db
class MyModel(BaseModel):
field1 = CharField()
field2 = DateTimeField()
58
29. Peewee — PostgreSQL and MySQL Extensions Peewee
hstore support.
server-side cursors.
full-text search.
Postgres hstore is a key:value store that can be embedded in a table as one of the fields
of type HStoreField. To enable hstore support, create database instance with
register_hstore=True parameter.
db = PostgresqlExtDatabase('mydatabase', register_hstore=True)
class Vehicles(BaseExtModel):
type = CharField()
features = HStoreField()
obj=Vehicle.get(Vehicle.id=v.id)
59
Peewee
print (obj.features)
MySQL Extensions
Alternate implementation of MysqlDatabase class is provided by
MySQLConnectorDatabase defined in playhouse.mysql_ext module. It uses Python’s
DB-API compatible official mysql/python connector.
60
30. Peewee — Using CockroachDB Peewee
Field Classes
The extension also has certain special field classes that are used as attribute in CRDB
compatible model.
UUIDKeyField - A primary-key field that uses CRDB’s UUID type with a default
randomly-generated UUID.
RowIDField - A primary-key field that uses CRDB’s INT type with a default
unique_rowid().
JSONField - Same as the Postgres BinaryJSONField.
ArrayField - Same as the Postgres extension, but does not support multi-
dimensional arrays.
61