Skip to content

What it is

Peewee is a small, expressive ORM (Object-Relational Mapping) library for Python. It provides a simple and lightweight way to interact with databases using Pythonic models and queries, supporting SQLite, MySQL, and PostgreSQL.

Peewee allows you to define models as Python classes that map to database tables. You can perform CRUD operations, define relationships, execute queries, and manage transactions with a simple and intuitive API.

Installation

pip install peewee

Getting started

The smallest useful thing you can do with it, and what each part means.

Defining a model
from peewee import Model, CharField, SqliteDatabase

db = SqliteDatabase('my_database.db')

class User(Model):
    name = CharField()
    email = CharField(unique=True)

    class Meta:
        database = db

db.connect()
db.create_tables([User])
Defines a `User` model with `name` and unique `email` fields, connects to a SQLite database, and creates the corresponding table.
Inserting a record
user = User.create(name='Alice', email='alice@example.com')
Creates a new user record and saves it to the database.

Advanced usage

Where the library earns its place over a simpler alternative.

Querying records
users = User.select().where(User.name == 'Alice')
for user in users:
    print(user.name, user.email)
Selects all users with the name 'Alice' and prints their details.
Updating records
query = User.update(email='alice_new@example.com').where(User.name=='Alice')
query.execute()
Updates the email of users with name 'Alice'.
Deleting records
query = User.delete().where(User.name=='Alice')
query.execute()
Deletes users with name 'Alice' from the database.
Defining relationships
from peewee import ForeignKeyField

class Post(Model):
    title = CharField()
    author = ForeignKeyField(User, backref='posts')

    class Meta:
        database = db
Defines a `Post` model with a foreign key relationship to the `User` model, allowing reverse lookups via `user.posts`.
Transactions
with db.atomic():
    User.create(name='Bob', email='bob@example.com')
    User.create(name='Charlie', email='charlie@example.com')
Performs multiple database operations within a transaction, ensuring atomicity.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

IntegrityError
Occurs when unique constraints or foreign key constraints are violated. Ensure input data respects constraints.
OperationalError
Check database connectivity, schema, or syntax for errors.
DoesNotExist
Raised when a query for a specific record does not return any results. Handle with try/except blocks or use `.get_or_none()`.

Best practices

  • Use `db.atomic()` for grouping multiple operations to ensure atomicity.
  • Define relationships with `ForeignKeyField` and `backref` for clean data access.
  • Use Peewee’s built-in query methods instead of raw SQL for consistency and safety.
  • Keep models modular and separated per app/module for maintainability.
  • Close database connections after use to prevent resource leaks.

Background

Why it exists, and what it was reacting to.

Peewee was created by Charles Leifer to provide a minimalistic ORM alternative that is easy to learn and integrate into Python projects. It emphasizes simplicity and readability while still offering sufficient functionality for most database tasks, making it popular for small to medium-sized applications.