Deleting an object

When you call the delete() method of an entity instance, Pony marks the object as deleted. The object will be removed from the database during the following commit.

For example, this is how we can delete an order with the primary key equal to 123:

  1. Order[123].delete()

Bulk delete

Pony supports bulk delete for objects using the delete() function. This way you can delete multiple objects without loading them to the cache:

  1. delete(p for p in Product if p.category.name == 'SD Card')
  2. #or
  3. Product.select(lambda p: p.category.name == 'SD Card').delete(bulk=True)

Note

Be careful with the bulk delete:

Cascade delete

When Pony deletes an instance of an entity it also needs to delete its relationships with other objects. The relationships between two objects are defined by two relationship attributes. If another side of the relationship is declared as a Set, then we just need to remove the object from that collection. If another side is declared as Optional, then we need to set it to None. If another side is declared as Required, we cannot just assign None to that relationship attribute. In this case, Pony will try to do a cascade delete of the related object.

This default behavior can be changed using the cascade_delete option of an attribute. By default this option is set to True when another side of the relationship is declared as Required and False for all other relationship types.

If the relationship is defined as Required at the other end and cascade_delete=False then Pony raises the ConstraintError exception on deletion attempt.

Let’s consider a couple of examples.

The example below raises the ConstraintError exception on an attempt to delete a group which has related students:

  1. class Group(db.Entity):
  2. major = Required(str)
  3. items = Set("Student", cascade_delete=False)
  4. class Student(db.Entity):
  5. name = Required(str)
  6. group = Required(Group)

In the following example, if a Person object has a related Passport object, then if you’ll try to delete the Person object, the Passport object will be deleted as well due to cascade delete:

  1. class Person(db.Entity):
  2. name = Required(str)
  3. passport = Optional("Passport", cascade_delete=True)
  4. class Passport(db.Entity):
  5. number = Required(str)
  6. person = Required("Person")