In Pony ORM, it is possible to ‘automatically’ create a many-to-many relationship. For example, from the documentation (for version 0.6, emphasis mine):
In order to create many-to-many relationship you need to define both ends of the relationship as Set attributes:
class Product(db.Entity): tags = Set("Tag") class Tag(db.Entity): products = Set(Product)
In order to implement this relationship in the database, Pony will create an intermediate table. This is a well known solution which allows you to have many-to-many relationships in relational databases.
Is it possible to create an extra attribute (column) in the automatically created intermediate table, so not just foreign keys to ‘Product’ and ‘Tag’, but, e.g., also a timestamp?
If yes, how?
If not, I guess I'll have to create the intermediate table explicitly. Can I in that case still use the nice Set
-attribute definition (perhaps to the intermediate table, indicating the attribute of interest)?
Currently it is necessary to define explicit entity, like this:
Pony does not support virtual
Set
attributes likethrough
in Django, but we plan to add them in the future. Right now you need to work with intermediate table explicitly.Adding a tag to a product
Removing a tag from a product:
Checking if a product has a specific tag:
Also, Pony support the concept of attribute lifting. That means that in Pony any collection attribute has all attributes of its items. The value of a such collection attribute is a collection of all values for individual items. For example, in order to get all tags for specific product, you can write:
The
p1.tags
expression returns a collection ofProductTag
items. EachProductTag
object hastag
property which points to a specific tag object. Sop1.tags.tag
returns a collection of allTag
objects linked with a specificProduct
object.It is possible to use attribute lifting inside queries. For example, in order to found all products with the tag
smartphones
you can write the following query:Here,
p.tags
is a colection ofProductTag
objects,p.tags.tag
is a collection ofTag
objects, andp.tags.tag.name
is a collection of tag names. The query above is a syntactic sugar for the following query:Also, the query can be rewritten as: