[파이썬] Peewee Custom aggregates 및 annotations

In this blog post, we will explore how to use Peewee’s custom aggregates and annotations in Python. Peewee is a powerful and lightweight Object Relational Mapping (ORM) library for Python, which makes working with databases a breeze.

Custom Aggregates

Peewee allows you to define custom aggregates, which are SQL functions that can be used in queries to perform complex calculations or aggregations on your data.

Let’s say we have a table called Order in our database and we want to calculate the total revenue for a particular product. Here’s how we can define a custom aggregate using Peewee:

from peewee import *

# Define a custom aggregate
class TotalRevenue(SQLiteAggregate):
    def __init__(self, expression, **kwargs):
        super().__init__(expression, **kwargs)
        self._name = 'total_revenue'

    def finalize(self):
        self._sql = f'SUM({self._expression})'

# Define the Order model
class Order(Model):
    product = CharField()
    price = DecimalField()

    class Meta:
        database = SqliteDatabase(':memory:')


# Use the custom aggregate in a query
query = Order.select(TotalRevenue(Order.price).alias('total'))
total_revenue = query.scalar()
print(total_revenue)

In the above code, we define a custom aggregate TotalRevenue, which calculates the sum of the price column. We then use this custom aggregate in a query to calculate the total revenue for all orders.

Custom Annotations

Annotations are similar to aggregates, but they are used to add additional information to each row rather than aggregating data across rows. Peewee allows you to define custom annotations using the annotations decorator.

Let’s say we have a table called Product and we want to calculate the discounted price for each product based on a discount percentage. Here’s how we can define a custom annotation using Peewee:

from peewee import *

# Define the Product model
class Product(Model):
    name = CharField()
    price = DecimalField()

    class Meta:
        database = SqliteDatabase(':memory:')

# Define a custom annotation
@Product.annotations(discounted_price=SQL('price * 0.9'))
class ProductWithDiscount(Product):
    pass

# Use the custom annotation in a query
products = ProductWithDiscount.select()
for product in products:
    print(product.name, product.discounted_price)

In the above code, we define a custom annotation discounted_price, which calculates the discounted price based on the original price column. We then use this custom annotation in a query to fetch all products with their discounted prices.

Peewee’s custom aggregates and annotations provide a flexible way to perform complex calculations and add additional information to your database queries. By leveraging these features, you can simplify your code, improve performance, and gain more control over your data analysis.

Whether you’re working with a small SQLite database or a large production PostgreSQL database, Peewee makes it easy to work with your data using Python’s familiar syntax.

Happy coding!