Skip to main content
https://media.charlesleifer.com/blog/photos/peewee4-logo.png

peewee

Peewee is a simple and small ORM. It has few (but expressive) concepts, making it easy to learn and intuitive to use.

Peewee is a single module with no required dependencies and has been running production workloads of all sizes since 2010.

  • a small, expressive ORM

  • flexible query-builder that exposes full power of SQL

  • supports sqlite, mysql, mariadb, postgresql

  • asyncio support built on the standard async drivers (aiosqlite, asyncpg, aiomysql)

  • schema migrations with diff-based generation (pwmigrate)

  • tons of extensions

  • use with flask, fastapi, pydantic, and more.

New to peewee? These may help:

Installation:

pip install peewee

Sqlite comes built-in provided by the standard-lib sqlite3 module. Other backends can be installed using the following instead:

pip install peewee[mysql]  # Install peewee with pymysql.
pip install peewee[postgres]  # Install peewee with psycopg2.
pip install peewee[psycopg3]  # Install peewee with psycopg3.

# AsyncIO implementations.
pip install peewee[aiosqlite]  # Install peewee with aiosqlite.
pip install peewee[aiomysql]  # Install peewee with aiomysql.
pip install peewee[asyncpg]  # Install peewee with asyncpg.

Examples

Defining models is similar to Django or SQLAlchemy:

from peewee import *
import datetime


db = SqliteDatabase('my_database.db')

class BaseModel(Model):
    class Meta:
        database = db

class User(BaseModel):
    username = CharField(unique=True)

class Tweet(BaseModel):
    user = ForeignKeyField(User, backref='tweets')
    message = TextField()
    created_date = DateTimeField(default=datetime.datetime.now)
    is_published = BooleanField(default=True)

Connect to the database and create tables:

db.connect()
db.create_tables([User, Tweet])

Create a few rows:

charlie = User.create(username='charlie')
huey = User(username='huey')
huey.save()

# No need to set `is_published` or `created_date` since they
# will just use the default values we specified.
Tweet.create(user=charlie, message='My first tweet')

Queries are expressive and composable:

# A simple query selecting a user.
User.get(User.username == 'charlie')

# Get tweets created by one of several users.
usernames = ['charlie', 'huey', 'mickey']
users = User.select().where(User.username.in_(usernames))
tweets = Tweet.select().where(Tweet.user.in_(users))

# We could accomplish the same using a JOIN:
tweets = (Tweet
          .select()
          .join(User)
          .where(User.username.in_(usernames)))

# How many tweets were published today?
tweets_today = (Tweet
                .select()
                .where(
                    (Tweet.created_date >= datetime.date.today()) &
                    (Tweet.is_published == True))
                .count())

# Paginate the user table and show me page 3 (users 41-60).
User.select().order_by(User.username).paginate(3, 20)

# Order users by the number of tweets they've created:
tweet_ct = fn.Count(Tweet.id)
users = (User
         .select(User, tweet_ct.alias('ct'))
         .join(Tweet, JOIN.LEFT_OUTER)
         .group_by(User)
         .order_by(tweet_ct.desc()))

# Do an atomic update (for illustrative purposes only, imagine a simple
# table for tracking a "count" associated with each URL). We don't want to
# naively get the save in two separate steps since this is prone to race
# conditions.
Counter.update(count=Counter.count + 1).where(Counter.url == request.url).execute()

Check out the example twitter app.

Asyncio

import asyncio
from peewee import *
from playhouse.pwasyncio import AsyncPostgresqlDatabase

db = AsyncPostgresqlDatabase('my_app')

class User(db.Model):
    username = CharField(unique=True)

class Tweet(db.Model):
    user = ForeignKeyField(User, backref='tweets')
    message = TextField()

async def main():
    async with db:
        await db.acreate_tables([User, Tweet])

        # Queries are awaited on the event loop using asyncpg.
        huey = await User.acreate(username='huey')
        tweet = await Tweet.acreate(user=huey, message='meow')

        async with db.atomic():
            tweet.message = 'purr'
            await tweet.asave()

        # Create a query - nothing is executed yet.
        query = Tweet.select(Tweet, User).join(User)

        # Execute and buffer the results.
        tweets = await query.aexecute()  # Or: await db.list(query)
        for tweet in tweets:
            print(tweet.user.username, '->', tweet.message)

        # Streaming results via server-side cursor.
        async for tweet in db.iterate(query):
            print(tweet.user.username, '->', tweet.message)

    await db.close_pool()

asyncio.run(main())

See the asyncio docs for details.

Learning more

Check the documentation for more examples.

Specific question? Come hang out in the #peewee channel on irc.libera.chat, or post to the mailing list, http://groups.google.com/group/peewee-orm . If you would like to report a bug, create a new issue on GitHub.

Still want more info?

https://media.charlesleifer.com/blog/photos/wat.jpg

I’ve written a number of blog posts about building applications and web-services with peewee (and usually Flask). If you’d like to see some real-life applications that use peewee, the following resources may be useful:

Metadata

Release files for peewee 4.5.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for peewee 4.5.3
File Size Uploaded
peewee-4.5.3.tar.gz 821.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for peewee 4.5.3
File Interpreter ABI Platform
peewee-4.5.3-py3-none-any.whl Python 3 none any Details

Total release size: 1.0 MB

Release files / peewee-4.5.3.tar.gz

Download URL peewee-4.5.3.tar.gz
Size 821.8 kB
Tags Source
SHA-256 checksum
How to use checksums
434576afaf806428a01f84af74c42fde59372c4f6a6eba26d9b5372113344a8a
BLAKE2b-256 checksum
How to use checksums
6f858142c26b9942e2993fdcd9163089a8531ac255aecef1ca4cc1b611e8d193
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / peewee-4.5.3-py3-none-any.whl

Download URL peewee-4.5.3-py3-none-any.whl
Size 194.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4c5db9d2a3c4ae9a5725b229c29af51dbd063193f3a6c03b837974a90e44548c
BLAKE2b-256 checksum
How to use checksums
76e31f3847b62db730a58c6f6d689c060d7228721f3a66e612a27cda297e875a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

4.5.3 This release

2 release files

4.5.2

2 release files

4.5.1

2 release files

4.5.0

2 release files

4.4.0

2 release files

4.3.0

2 release files

4.2.6

2 release files

4.2.5

2 release files

4.2.4

2 release files

4.2.3

2 release files

4.2.2

2 release files

4.2.1

2 release files

4.2.0

2 release files

4.1.2

2 release files

4.1.1

2 release files

4.1.0

2 release files

4.0.9

2 release files

4.0.8

2 release files

4.0.7

2 release files

4.0.6

2 release files

4.0.5

2 release files

4.0.4

2 release files

4.0.3

2 release files

4.0.2

2 release files

4.0.1

2 release files

4.0.0

2 release files

3.18.3

1 release file

3.18.2

1 release file

3.18.1

1 release file

3.18.0

1 release file

3.17.9

1 release file

3.17.8

1 release file

3.17.7

1 release file

3.17.6

1 release file

3.17.5

1 release file

3.17.4

1 release file

3.17.3

1 release file

3.17.2

1 release file

3.17.1

1 release file

3.17.0

1 release file

3.16.3

1 release file

3.16.2

1 release file

3.16.1

1 release file

3.16.0

1 release file

3.15.4

1 release file

3.15.3

1 release file

3.15.2

1 release file

3.15.1

1 release file

3.15.0

1 release file

3.14.9

1 release file

3.14.8

1 release file

3.14.7

1 release file

3.14.6

1 release file

3.14.4

1 release file

3.14.3

1 release file

3.14.2

1 release file

3.14.1

1 release file

3.14.0

1 release file

3.13.3

1 release file

3.13.2

1 release file

3.13.1

1 release file

3.13.0

1 release file

3.12.0

1 release file

3.11.2

1 release file

3.11.1

1 release file

3.11.0

1 release file

3.10.0

1 release file

3.9.6

1 release file

3.9.5

1 release file

3.9.4

1 release file

3.9.3

1 release file

3.9.2

1 release file

3.9.1

1 release file

3.9.0

1 release file

3.8.2

1 release file

3.8.1

1 release file

3.8.0

1 release file

3.7.1

1 release file

3.7.0

1 release file

3.6.4

1 release file

3.6.3

1 release file

3.6.2

1 release file

3.6.1

1 release file

3.6.0

1 release file

3.5.2

1 release file

3.5.1

1 release file

3.5.0

1 release file

3.4.0

1 release file

3.3.4

1 release file

3.3.3

1 release file

3.3.2

1 release file

3.3.1

1 release file

3.3.0

1 release file

3.2.5

1 release file

3.2.4

1 release file

3.2.3

1 release file

3.2.2

1 release file

3.2.1

1 release file

3.2.0

1 release file

3.1.7

1 release file

3.1.6

1 release file

3.1.5

1 release file

3.1.4

1 release file

3.1.3

1 release file

3.1.2

1 release file

3.1.1

1 release file

3.1.0

1 release file

3.0.19

1 release file

3.0.18

1 release file

3.0.17

1 release file

3.0.16

1 release file

3.0.15

1 release file

3.0.14

1 release file

3.0.13

1 release file

3.0.12

1 release file

3.0.11

1 release file

3.0.10

1 release file

3.0.9

1 release file

3.0.8

1 release file

3.0.7

1 release file

3.0.6

1 release file

3.0.5

1 release file

3.0.4

1 release file

3.0.3

1 release file

3.0.2

1 release file

3.0.1

1 release file

2.10.2

1 release file

2.10.1

1 release file

2.10.0

1 release file

2.9.2

1 release file

2.9.1

1 release file

2.9.0

1 release file

2.8.8

1 release file

2.8.7

1 release file

2.8.5

1 release file

2.8.4

1 release file

2.8.3

1 release file

2.8.2

1 release file

2.8.1

1 release file

2.8.0

1 release file

2.7.4

1 release file

2.7.3

1 release file

2.7.2

1 release file

2.7.1

1 release file

2.7.0

1 release file

2.6.4

1 release file

2.6.3

1 release file

2.6.2

1 release file

2.6.1

1 release file

2.6.0

1 release file

2.5.1

1 release file

2.5.0

1 release file

2.4.7

1 release file

2.4.6

1 release file

2.4.5

1 release file

2.4.4

1 release file

2.4.3

1 release file

2.4.2

1 release file

2.4.1

1 release file

2.4.0

1 release file

2.3.3

1 release file

2.3.2

1 release file

2.3.1

1 release file

2.3.0

1 release file

2.2.5

1 release file

2.2.4

1 release file

2.2.3

1 release file

2.2.2

1 release file

2.2.1

1 release file

2.2.0

1 release file

2.1.7

1 release file

2.1.6

1 release file

2.1.5

1 release file

2.1.4

1 release file

2.1.3

1 release file

2.1.2

1 release file

2.1.1

1 release file

2.1.0

1 release file

2.0.9

1 release file

2.0.8

1 release file

2.0.7

1 release file

2.0.6

1 release file

2.0.5

1 release file

2.0.4

1 release file

2.0.3

1 release file

2.0.2

1 release file

2.0.1

1 release file

2.0.0

1 release file

1.0.0

1 release file

0.9.9

1 release file

0.9.8

1 release file

0.9.7

1 release file

0.9.6

1 release file

0.9.5

1 release file

0.9.4

1 release file

0.9.3

1 release file

0.9.2

1 release file

0.9.1

1 release file

0.9.0

1 release file

0.8.2

1 release file

0.8.1

1 release file

0.8.0

1 release file

0.7.5

1 release file

0.7.4

1 release file

0.7.3

1 release file

0.7.2

1 release file

0.7.1

1 release file

0.7.0

1 release file

0.6.2

1 release file

0.6.1

1 release file

0.6.0

1 release file

0.5.0

1 release file

0.4.0

1 release file

0.3.2

1 release file

0.3.1

1 release file

0.3.0

1 release file

0.2.2

1 release file

0.2.1

1 release file

0.2.0

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page