Queries and functions

Below is the list of upper level functions defined in Pony:

avg(gen, distinct=None)

Return the average value for all selected attributes.

  • Parameters

    • gen (generator) – Python generator expression

    • distinct (bool) – distinct option

    Return type

    numeric

  1. avg(o.total_price for o in Order)

The equivalent query can be generated using the avg() method.

between(x, a, b)

This function will be translated into x BETWEEN a AND b. It is equal to the condition x >= a AND x <= b.

  1. select(p for p in Person if between(p.age, 18, 65))

coalesce(\args*)

  • Parameters

    args (list) – list of arguments

Returns the first non-null expression in a list.

  1. select(coalesce(p.phone, 'UNKNOWN') for p in Person)

concat(\args*)

  • Parameters

    args (list) – list of arguments

Concatenates arguments into one string.

  1. select(concat(p.first_name, ' ', p.last_name) for p in Person)

commit()

Save all changes which were made within the current db_session() using the flush() function and commits the transaction to the database. This top level commit() function calls the commit() method of each database object which was used in current transaction.

count(gen, distinct=None)

Return the number of objects that match the query condition.

  • Parameters

    • gen (generator) – Python generator expression

    • distinct (bool) – distinct option

    Return type

    numeric

  1. count(c for c in Customer if len(c.orders) > 2)

This query will be translated to the following SQL:

  1. SELECT COUNT(*)
  2. FROM "Customer" "c"
  3. LEFT JOIN "Order" "order-1"
  4. ON "c"."id" = "order-1"."customer"
  5. GROUP BY "c"."id"
  6. HAVING COUNT(DISTINCT "order-1"."id") > 2

The equivalent query can be generated using the count() method.

delete(gen)

Delete objects from the database. Pony loads objects into the memory and will delete them one by one. If you have before_delete() or after_delete() defined, Pony will call each of them.

  • Parameters

    gen (generator) – Python generator expression

  1. delete(o for o in Order if o.status == 'CANCELLED')

If you need to delete objects without loading them into memory, you should use the delete() method with the parameter bulk=True. In this case no hooks will be called, even if they are defined for the entity.

desc(attr)

This function is used inside order_by() and sort_by() for ordering in descending order.

  • Parameters

    attr (attribute) – Entity attribute

  1. select(o for o in Order).order_by(desc(Order.date_shipped))

The same example, using lambda:

  1. select(o for o in Order).order_by(lambda o: desc(o.date_shipped))

distinct(gen)

When you need to force DISTINCT in a query, it can be done using the distinct() function. But usually this is not necessary, because Pony adds DISTINCT keyword automatically in an intelligent way. See more information about it in the TODO chapter.

  • Parameters

    gen (generator) – Python generator expression

  1. distinct(o.date_shipped for o in Order)

Another usage of the distinct() function is with the sum() aggregate function - you can write:

  1. select(sum(distinct(x.val)) for x in X)

to generate the following SQL:

  1. SELECT SUM(DISTINCT x.val)
  2. FROM X x

but it is rarely used in practice.

exists(gen, globals=None, locals=None)

Returns True if at least one instance with the specified condition exists and False otherwise.

  • Parameters

    • gen (generator) – Python generator expression.

    • globals (dict) –

    • locals (dict) – optional parameters which can contain dicts with variables and its values, used within the query.

    Return type

    bool

  1. exists(o for o in Order if o.date_delivered is None)

flush()

Save all changes from the db_session() cache to the databases, without committing them. It makes the updates made in the db_session() cache visible to all database queries which belong to the current transaction.

Usually Pony saves data from the database session cache automatically and you don’t need to call this function yourself. One of the use cases when it might be needed is when you want to get the primary keys values of newly created objects which has autoincremented primary key before commit.

This top level flush() function calls the flush() method of each database object which was used in current transaction.

This function is called automatically before executing the following functions: commit(), get(), exists(), select().

get(gen, globals=None, locals=None)

Extracts one entity instance from the database.

  • Parameters

    • gen (generator) – Python generator expression.

    • globals (dict) –

    • locals (dict) – optional parameters which can contain dicts with variables and its values, used within the query.

    Returns

    the object if an object with the specified parameters exists, or None if there is no such object.

If there are more than one objects with the specified parameters, the function raises the MultipleObjectsFoundError: Multiple objects were found. Use select(...) to retrieve them exception.

  1. get(o for o in Order if o.id == 123)

The equivalent query can be generated using the get() method.

getattr(object, name[, default])

This is a standard Python built-in function, that can be used for getting the attribute value inside the query.

Example:

  1. attr_name = 'name'
  2. param_value = 'John'
  3. select(c for c in Customer if getattr(c, attr_name) == param_value)

group_concat(gen, sep=’,’, distinct=False)

(new in version 0.7.4)

Returns string which is concatenation of given attribute.

  1. group_concat(t.title for t in Tag, sep='-')

The equivalent query can be generated using the group_concat() method.

Note

Query should return only single attribute. Also in SQLite you cant use both distinct and sep arguments at a time.

JOIN(\args*)

Used for query optimization in cases when Pony doesn’t provide this optimization automatically. Serves as a hint saying Pony that we want to use SQL JOIN, instead of generating a subquery inside the SQL query.

  1. select(g for g in Group if max(g.students.gpa) < 4)
  2. select(g for g in Group if JOIN(max(g.students.gpa) < 4))

left_join(gen, globals=None, locals=None)

The results of a left join always contain the result from the ‘left’ table, even if the join condition doesn’t find any matching record in the ‘right’ table.

  • Parameters

    • gen (generator) – Python generator expression.

    • globals (dict) –

    • locals (dict) – optional parameters which can contain dicts with variables and its values, used within the query.

Let’s say we need to calculate the amount of orders for each customer. Let’s use the example which comes with Pony distribution and write the following query:

  1. from pony.orm.examples.estore import *
  2. populate_database()
  3. select((c, count(o)) for c in Customer for o in c.orders)[:]

It will be translated to the following SQL:

  1. SELECT "c"."id", COUNT(DISTINCT "o"."id")
  2. FROM "Customer" "c", "Order" "o"
  3. WHERE "c"."id" = "o"."customer"
  4. GROUP BY "c"."id"

And return the following result:

  1. [(Customer[1], 2), (Customer[2], 1), (Customer[3], 1), (Customer[4], 1)]

But if there are customers that have no orders, they will not be selected by this query, because the condition WHERE "c"."id" = "o"."customer" doesn’t find any matching record in the Order table. In order to get the list of all customers, we should use the left_join() function:

  1. left_join((c, count(o)) for c in Customer for o in c.orders)[:]
  1. SELECT "c"."id", COUNT(DISTINCT "o"."id")
  2. FROM "Customer" "c"
  3. LEFT JOIN "Order" "o"
  4. ON "c"."id" = "o"."customer"
  5. GROUP BY "c"."id"

Now we will get the list of all customers with the number of order equal to zero for customers which have no orders:

  1. [(Customer[1], 2), (Customer[2], 1), (Customer[3], 1), (Customer[4], 1), (Customer[5], 0)]

We should mention that in most cases Pony can understand where LEFT JOIN is needed. For example, the same query can be written this way:

  1. select((c, count(c.orders)) for c in Customer)[:]
  1. SELECT "c"."id", COUNT(DISTINCT "order-1"."id")
  2. FROM "Customer" "c"
  3. LEFT JOIN "Order" "order-1"
  4. ON "c"."id" = "order-1"."customer"
  5. GROUP BY "c"."id"

len(arg)

Return the number of objects in the collection. Can be used only within the query, similar to count().

  • Parameters

    arg (generator) – a collection

    Return type

    numeric

  1. Customer.select(lambda c: len(c.orders) > 2)

max(gen)

Return the maximum value from the database. The query should return a single attribute.

  • Parameters

    gen (generator) – Python generator expression.

  1. max(o.date_shipped for o in Order)

The equivalent query can be generated using the max() method.

min(\args, **kwargs*)

Return the minimum value from the database. The query should return a single attribute.

  • Parameters

    gen (generator) – Python generator expression.

  1. min(p.price for p in Product)

The equivalent query can be generated using the min() method.

random()

Returns a random value from 0 to 1. This functions, when encountered inside a query will be translated into RANDOM SQL query.

Example:

  1. select(s.gpa for s in Student if s.gpa > random() * 5)
  1. SELECT DISTINCT "s"."gpa"
  2. FROM "student" "s"
  3. WHERE "s"."gpa" > (random() * 5)

raw_sql(sql, result_type=None)

This function encapsulates a part of a query expressed in a raw SQL format. If the result_type is specified, Pony converts the result of raw SQL fragment to the specified format.

  • Parameters

    • sql (str) – SQL statement text.

    • result_type (type) – the type of the SQL statement result.

  1. >>> q = Person.select(lambda x: raw_sql('abs("x"."age")') > 25)
  2. >>> print(q.get_sql())
  1. SELECT "x"."id", "x"."name", "x"."age", "x"."dob"
  2. FROM "Person" "x"
  3. WHERE abs("x"."age") > 25
  1. x = 10
  2. y = 15
  3. select(p for p in Person if raw_sql('p.age > $(x + y)'))
  4. names = select(raw_sql('UPPER(p.name)') for p in Person)[:]
  5. print(names)
  6. ['JOHN', 'MIKE', 'MARY']

See more examples here.

rollback()

Roll back the current transaction.

This top level rollback() function calls the rollback() method of each database object which was used in current transaction.

select(gen)

Translates the generator expression into SQL query and returns an instance of the Query class.

  • Parameters

    • gen (generator) – Python generator expression.

    • globals (dict) –

    • locals (dict) – optional parameters which can contain dicts with variables and its values, used within the query.

    Return type

    Query or list

You can iterate over the result:

  1. for p in select(p for p in Product):
  2. print p.name, p.price

If you need to get a list of objects you can get a full slice of the result:

  1. prod_list = select(p for p in Product)[:]

The select() function can also return a list of single attributes or a list of tuples:

  1. select(p.name for p in Product)
  2. select((p1, p2) for p1 in Product
  3. for p2 in Product if p1.name == p2.name and p1 != p2)
  4. select((p.name, count(p.orders)) for p in Product)

You can apply any Query method to the result, e.g. order_by() or count().

If you want to run a query over a relationship attribute, you can use the select() method of the relationship attribute.

show()

Prints out the entity definition or the value of attributes for an entity instance in the interactive mode.

  • Parameters

    value – entity class or entity instance

  1. >>> show(Person)
  2. class Person(Entity):
  3. id = PrimaryKey(int, auto=True)
  4. name = Required(str)
  5. age = Required(int)
  6. cars = Set(Car)
  7. >>> show(mary)
  8. instance of Person
  9. id|name|age
  10. --+----+---
  11. 2 |Mary|22

set_sql_debug(value=True, show_values=None)

Prints SQL statements being sent to the database to the console or to a log file. Previous name sql_debug is deprecated.

  • Parameters

    • value (bool) – sets debugging on/off

    • show_values (bool) – when True, query parameters will be logged in addition to the SQL text (new in version 0.7.3)

Before version 0.7.3 it was a global flag. Now, in multi-threaded application, it should be set for each thread separately.

By default Pony sends debug information to stdout. If you have the standard Python logging configured, Pony will use it instead. Here is how you can store debug information in a file:

  1. import logging
  2. logging.basicConfig(filename='pony.log', level=logging.INFO)

Note, that we had to specify the level=logging.INFO because the default standard logging level is WARNING and Pony uses the INFO level for its messages by default. Pony uses two loggers: pony.orm.sql for SQL statements that it sends to the database and pony.orm for all other messages.

sql_debugging(value=True, show_values=None)

Context manager, use it for enabling/disabling logging SQL queries for a specific part of your code. If you need to turn on debugging for the whole db_session, use the similar parameters of db_session() decorator or context manager.

  • Parameters

    • value (bool) – sets debugging on/off

    • show_values (bool) – when True, query parameters will be logged in addition to the SQL text (new in version 0.7.3)

  1. with sql_debugging: # turn debug on for a specific query
  2. result = Person.select()
  3. with sql_debugging(show_values=True): # log with query params
  4. result = Person.select()
  5. with sql_debugging(False): # turn debug off for a specific query
  6. result = Person.select()

sum(gen, distinct=None)

Return the sum of all values selected from the database.

  • Parameters

    • gen (generator) – Python generator expression

    • distinct (bool) – distinct option

    Return type

    numeric

    Returns

    a number. If the query returns no items, the sum() method returns 0.

  1. sum(o.total_price for o in Order)

The equivalent query can be generated using the sum() method.

make_proxy(obj)

Make a proxy object for given object. By proxy object we call object which can be used in different sessions. It might be useful for applications that are not request-based (for example GUI standalone application).

  • Parameters

    obj (entity) – entity object

    Return type

    EntityProxy

    Returns

    proxy object.

  1. with db_session:
  2. user = User[id]
  3. current_user = make_proxy(user)
  4. ...
  5. with db_session:
  6. print(current_user.name)