Pony query examples

For demonstrating Pony queries let’s use the example from the Pony ORM distribution. You can try these queries yourself in the interactive mode and see the generated SQL. For this purpose import the example module this way:

  1. >>> from pony.orm.examples.estore import *

This module offers a simplified data model of a eCommerce online store. Here is the ER Diagram of the data model:

_images/estore.png

Here are the entity definitions:

  1. from decimal import Decimal
  2. from datetime import datetime
  3. from pony.converting import str2datetime
  4. from pony.orm import *
  5. db = Database()
  6. class Customer(db.Entity):
  7. email = Required(str, unique=True)
  8. password = Required(str)
  9. name = Required(str)
  10. country = Required(str)
  11. address = Required(str)
  12. cart_items = Set('CartItem')
  13. orders = Set('Order')
  14. class Product(db.Entity):
  15. id = PrimaryKey(int, auto=True)
  16. name = Required(str)
  17. categories = Set('Category')
  18. description = Optional(str)
  19. picture = Optional(buffer)
  20. price = Required(Decimal)
  21. quantity = Required(int)
  22. cart_items = Set('CartItem')
  23. order_items = Set('OrderItem')
  24. class CartItem(db.Entity):
  25. quantity = Required(int)
  26. customer = Required(Customer)
  27. product = Required(Product)
  28. class OrderItem(db.Entity):
  29. quantity = Required(int)
  30. price = Required(Decimal)
  31. order = Required('Order')
  32. product = Required(Product)
  33. PrimaryKey(order, product)
  34. class Order(db.Entity):
  35. id = PrimaryKey(int, auto=True)
  36. state = Required(str)
  37. date_created = Required(datetime)
  38. date_shipped = Optional(datetime)
  39. date_delivered = Optional(datetime)
  40. total_price = Required(Decimal)
  41. customer = Required(Customer)
  42. items = Set(OrderItem)
  43. class Category(db.Entity):
  44. name = Required(str, unique=True)
  45. products = Set(Product)
  46. set_sql_debug(True)
  47. db.bind('sqlite', 'estore.sqlite', create_db=True)
  48. db.generate_mapping(create_tables=True)

When you import this example, it will create the SQLite database in the file ‘estore.sqlite’ and fill it with some test data. Below you can see some query examples:

  1. # All USA customers
  2. Customer.select(lambda c: c.country == 'USA')
  3. # The number of customers for each country
  4. select((c.country, count(c)) for c in Customer)
  5. # Max product price
  6. max(p.price for p in Product)
  7. # Max SSD price
  8. max(p.price for p in Product
  9. for cat in p.categories if cat.name == 'Solid State Drives')
  10. # Three most expensive products
  11. Product.select().order_by(desc(Product.price))[:3]
  12. # Out of stock products
  13. Product.select(lambda p: p.quantity == 0)
  14. # Most popular product
  15. Product.select().order_by(lambda p: desc(sum(p.order_items.quantity))).first()
  16. # Products that have never been ordered
  17. Product.select(lambda p: not p.order_items)
  18. # Customers who made several orders
  19. Customer.select(lambda c: count(c.orders) > 1)
  20. # Three most valuable customers
  21. Customer.select().order_by(lambda c: desc(sum(c.orders.total_price)))[:3]
  22. # Customers whose orders were shipped
  23. Customer.select(lambda c: SHIPPED in c.orders.state)
  24. # Customers with no orders
  25. Customer.select(lambda c: not c.orders)
  26. # The same query with the LEFT JOIN instead of NOT EXISTS
  27. left_join(c for c in Customer for o in c.orders if o is None)
  28. # Customers which ordered several different tablets
  29. select(c for c in Customer
  30. for p in c.orders.items.product
  31. if 'Tablets' in p.categories.name and count(p) > 1)

You can find more queries in the pony.orm.examples.estore module.