Defining entities

Now, let’s create two entities – Person and Car. The entity Person has two attributes – name and age, and Car has attributes make and model. In the Python interpreter, type the following code:

  1. >>> class Person(db.Entity):
  2. ... name = Required(str)
  3. ... age = Required(int)
  4. ... cars = Set('Car')
  5. ...
  6. >>> class Car(db.Entity):
  7. ... make = Required(str)
  8. ... model = Required(str)
  9. ... owner = Required(Person)
  10. ...
  11. >>>

The classes that we have created are derived from the Database.Entity attribute of the Database object. It means that they are not ordinary classes, but entities. The entity instances are stored in the database, which is bound to the db variable. With Pony you can work with several databases at the same time, but each entity belongs to one specific database.

Inside the entity Person we have created three attributes – name, age and cars. The name and age are mandatory attributes. In other words, these attributes cannot have the None value. The name is a string attribute, while age is numeric.

The cars attribute is declared as Set and has the Car type. This means that this is a relationship. It can keep a collection of instances of the Car entity. "Car" is specified as a string here because we didn’t declare the entity Car by that moment yet.

The Car entity has three mandatory attributes: make and model are strings, and the owner attribute is the other side of the one-to-many relationship. Relationships in Pony are always defined by two attributes which represent both sides of a relationship.

If we need to create a many-to-many relationship between two entities, we should declare two Set attributes at both ends. Pony creates the intermediate database table automatically.

The str type is used for representing an unicode string in Python 3. Python 2 has two types for strings - str and unicode. Starting with the Pony Release 0.6, you can use either str or unicode for string attributes, both of them mean an unicode string. We recommend using the str type for string attributes, because it looks more natural in Python 3.

If you need to check an entity definition in the interactive mode, you can use the show() function. Pass the entity class or the entity instance to this function for printing out the definition:

  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)

You may notice that the entity got one extra attribute named id. Why did that happen?

Each entity must contain a primary key, which allows distinguishing one entity from the other. Since we have not set the primary key attribute manually, it was created automatically. If the primary key is created automatically, it is named as id and has a numeric format. If the primary key attribute is created manually, you can specify the name and type of your choice. Pony also supports composite primary keys.

When the primary key is created automatically, it always has the option auto set to True. It means that the value for this attribute will be assigned automatically using the database’s incremental counter or a database sequence.