PyPika for Tortoise-ORM
pypika-tortoise is an extension of the PyPika SQL query builder library, specifically designed to integrate seamlessly with Tortoise-ORM. It enables users to construct complex SQL queries using a Pythonic API directly from Tortoise-ORM models, leveraging PyPika's powerful query generation capabilities while ensuring compatibility with Tortoise-ORM's database interactions. The current version is 0.6.5, with its development closely tied to updates in `pypika` and `tortoise-orm`.
Warnings
- gotcha pypika-tortoise extends and wraps the original pypika library. While many pypika features are available, some specialized components (e.g., `QueryBuilder`) might be absent or replaced by pypika-tortoise's own constructs for better Tortoise-ORM integration. Always consult pypika-tortoise's documentation for features specific to its Tortoise-ORM integration.
- gotcha The `Table` and `Field` objects in `pypika-tortoise` gain special capabilities when initialized with Tortoise-ORM models. If `Table` is created with a plain string (e.g., `Table('my_table')`) or `Field` is used without a model context, it will behave like standard `pypika` objects, potentially leading to inconsistencies if Tortoise-ORM-specific features are expected.
- gotcha When constructing queries, especially with aggregate functions like `fn.Count` or `fn.Sum`, ensure that the field arguments correctly resolve to Tortoise-ORM model fields (e.g., `products_table.id`). Mixing raw strings or incorrectly referenced fields can lead to malformed SQL or runtime errors when Tortoise-ORM attempts to execute the query.
Install
-
pip install pypika-tortoise
Imports
- Query
from pypika_tortoise import Query
- Table
from pypika_tortoise import Table
- Field
from pypika_tortoise import Field
- functions
from pypika_tortoise import functions as fn
Quickstart
from tortoise import fields, models
from pypika_tortoise import Query, Table, functions as fn
# Define a Tortoise-ORM Model
class Product(models.Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
price = fields.DecimalField(max_digits=10, decimal_places=2)
in_stock = fields.BooleanField(default=True)
class Meta:
table = "products" # Ensure the table name is set
# Create a Table object from the Tortoise-ORM Model
products_table = Table(Product)
# Build a query using pypika-tortoise, referencing model fields
query = Query.from_(products_table).select(
products_table.id,
products_table.name,
products_table.price
).where(
products_table.in_stock == True
).orderby(
products_table.name
).limit(10)
# Generate the SQL string (does not execute against a DB)
sql_query = query.get_sql()
print(f"Generated SELECT SQL:\n{sql_query}")
# Example with aggregation using pypika_tortoise functions
query_agg = Query.from_(products_table).select(
fn.Count(products_table.id).as_('total_products'),
fn.Sum(products_table.price).as_('total_price_in_stock')
).where(
products_table.in_stock == True
)
sql_agg_query = query_agg.get_sql()
print(f"\nGenerated AGGREGATION SQL:\n{sql_agg_query}")