Peewee

Language: Python

Data

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.

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.

Installation

pip: pip install peewee
conda: conda install -c conda-forge peewee

Usage

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.

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.

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.

Error Handling

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.