Operations with collections
The attribute Person.cars
is represented as a collection and hence we can use regular operations that applicable to collections: add()
, remove()
, in
, len()
, clear()
.
You can add or remove relationships using the Set.add()
and Set.remove()
methods:
>>> p1.cars.remove(Car[1])
>>> print p1.cars
CarSet([])
>>> p1.cars.add(Car[1])
>>> print p1.cars
CarSet([Car[1]])
You can check if a collection contains an element:
>>> Car[1] in p1.cars
True
Or make sure that there is no such element in the collection:
>>> Car[1] not in p1.cars
False
Check the collection length:
>>> len(p1.cars)
1
If you need to create an instance of a car and assign it with a particular person instance, there are several ways to do it. One of the options is to call the create()
method of the collection attribute:
>>> p1.cars.create(model='Toyota', make='Prius')
>>> commit()
Now we can check that a new Car
instance was added to the Person.cars
collection attribute of our instance:
>>> print p1.cars
CarSet([Car[2], Car[1]])
>>> p1.cars.count()
2
You can iterate over a collection attribute:
>>> for car in p1.cars:
... print car.model
Toyota
Camry
Attribute lifting
In Pony, the collection attributes provides the attribute lifting capability: the collection obtains its items’ attributes:
>>> show(Car)
class Car(Entity):
id = PrimaryKey(int, auto=True)
make = Required(str)
model = Required(str)
owner = Optional(Person)
>>> p1 = Person[1]
>>> print p1.cars.model
Multiset({u'Camry': 1, u'Prius': 1})
Here we print out the entity declaration using the show()
function and then print the value of the model
attribute of the cars
relationship attribute. The cars
attribute has all the attributes of the Car
entity: id
, make
, model
and owner
. In Pony we call this a Multiset and it is implemented using a dictionary. The dictionary’s key represents the value of the attribute - ‘Camry’ and ‘Prius’ in our example. And the dictionary’s value shows how many times it encounters in this collection.
>>> print p1.cars.make
Multiset({u'Toyota': 2})
Person[1]
has two Toyotas.
We can iterate over the multiset:
>>> for m in p1.cars.make:
... print m
...
Toyota
Toyota
Collection attribute parameters
Here is the list options that you can apply to collection attributes:
Example:
class Photo(db.Entity):
tags = Set('Tag', table='photo_to_tag', column='tag_id')
class Tag(db.Entity):
photos = Set(Photo)
Collection attribute queries and other methods
Starting with the release 0.6.1, Pony introduces queries for the relationship attributes.
You can use the following methods of the relationship attribute for retrieving data:
See the Collection attribute methods part of th API Reference for more details.
Below you can find several examples of using these methods. We’ll use the University schema for showing these queries, here are python entity definitions and Entity-Relationship diagram.
The example below selects all students with the gpa
greater than 3 within the group 101:
g = Group[101]
g.students.filter(lambda student: student.gpa > 3)[:]
This query can be used for displaying the second page of group 101 student’s list ordered by the name
attribute:
g.students.order_by(Student.name).page(2, pagesize=3)
The same query can be also written in the following form:
g.students.order_by(lambda s: s.name).limit(3, offset=3)
The following query returns two random students from the group 101:
g.students.random(2)
And one more example. This query returns the first page of courses which were taken by Student[1]
in the second semester, ordered by the course name:
s = Student[1]
s.courses.select(lambda c: c.semester == 2).order_by(Course.name).page(1)