impl#

The user can define the relationship (one-to-many, many-to-many) between entities.

There are three types of DynamoDB item:

  • Entity: the main item that represents the entity.

  • OneToManyRelationship: the item that represents the one-to-many relationship.

  • ManyToManyRelationship: the item that represents the many-to-many relationship.

Let’s use YouTube as an example:

  • Entity: User, Video, Channel, Playlist.

  • OneToManyRelationship: Video Ownership, Channel Ownership, Playlist Ownership.

  • ManyToManyRelationship: Video Channel Association, Video Playlist Association,

    User Subscription, Channel Subscription.

All three types of items has to have a unique name. The name will be used in partition key, sort key and type attribute naming convention. I recommend to keep the name short and simple.

One the user declared the relationship metadata, the RelationshipSetting will be a helper class to provide lots of utility functions to Create, Update, Delete and Select items by relationship.

class pynamodb_mate.patterns.relationship_v2.impl.EntityType(name: str)[source]#
class pynamodb_mate.patterns.relationship_v2.impl.RelationshipType(name: str)[source]#
class pynamodb_mate.patterns.relationship_v2.impl.OneToManyRelationshipType(name: str, one_type: Type[T_BASE_ENTITY], many_type: Type[T_BASE_ENTITY])[source]#

one-to-many relationship. For example, “one” Google account can have “many” YouTube videos.

The “many” entity id, YouTube video id always be the partition key, and the “one” entity id, Google account id always be the sort key.

Parameters:
  • one_type – the “one” entity type.

  • many_type – the “many” entity type.

class pynamodb_mate.patterns.relationship_v2.impl.ManyToManyRelationshipType(name: str, left_type: Type[T_BASE_ENTITY], right_type: Type[T_BASE_ENTITY])[source]#

many-to-many relationship. For example, a playlist can have many videos, and a video can be in many playlists. It is critical to know which entity is on the left and which entity is on the right. Because the left entity and the right entity could be the same in certain relationship. For example, user can subscribe another user.

Parameters:
  • left_type – the left entity type.

  • right_type – the right entity type.

class pynamodb_mate.patterns.relationship_v2.impl.BaseLookupIndex[source]#

The lookup index uses the sort key as the hash key to provide reverse lookup capability.

class pynamodb_mate.patterns.relationship_v2.impl.BaseEntity(hash_key: Optional[Any] = None, range_key: Optional[Any] = None, **attributes)[source]#

Main entity item. Base class for all entity items and relationship items. In DynamoDB, we put all kinds of entities into the same table, and use the type attribute to distinguish them.

It has to have a BaseLookupIndex as the lookup index. You can declare more index as needed.

Parameters:
  • pk – partition key can only have alpha letter and hyphen. You can NOT use underscore in the partition key. For entity item, it is the unique id.

  • sk – sort key can only have alpha letter and hyphen.

For entity item, it is always “${entity_id}_–root–”. For relationship item,

pk and sk are the two unique ids of the two related entities.

Parameters:
  • type – item type, can be used to filter by the type.

  • name – human friendly name of the entity.

  • create_at – the creation time of the entity.

  • update_at – the last update time of the entity.

  • deleted – if True, the entity is deleted (softly).

get_vip_attrs() Dict[str, Any][source]#

Get all important attributes for the entity.

classmethod new_entity(id: str, name: str, save: bool = True, **kwargs) Optional[Self][source]#

Create a new entity.

Parameters:
  • e_type

  • id – unique id for the entity.

  • name – human-friendly name for the entity.

  • save – if True, save the entity to DynamoDB. Otherwise, just create the in-memory entity.

  • kwargs – additional parameters for the constructor.

classmethod set_one_to_many(conn: Connection, many_entity_id: str, one_entity_id: str, client_request_token: Optional[str] = None)[source]#

For example, in YouTube use case, one user has many videos, one video only belongs to one user. Then, this function is used to set ownership of a video. In this case, the video is the many entity, the user is the one entity.

If a video already has an owner, this function will delete the old relationship first then create a new relationship.

Parameters:
  • connpynamodb_mate.Connection object.

  • many_entity_id – the many entity id.

  • one_entity_id – the one entity id.

classmethod unset_one_to_many(conn: Connection, many_entity_id: str, client_request_token: Optional[str] = None)[source]#

Unset the one-to-many relationship.

Parameters:
  • connpynamodb_mate.Connection object.

  • many_entity_id – the many entity id.

classmethod find_one_by_many(many_entity_id: str) Optional[T_BASE_ENTITY][source]#

For example, in YouTube use case, one user has “many” YouTube videos. This function will find the owner of the given YouTube video.

Parameters:

many_entity_id – the many entity id.

classmethod find_many_by_one(one_entity_id: str) Iterable[T_BASE_ENTITY][source]#

For example, in YouTube use case, one user has “many” YouTube videos. This function will find the all videos owned by the given user.

Parameters:

one_entity_id – the one entity id.

classmethod set_many_to_many(left_entity_id: str, right_entity_id: str)[source]#

For example, in YouTube use case, one playlist has “many” videos. One video can be in “many” playlists. This function will add the video to the playlist.

Parameters:
  • left_entity_id – the left entity id.

  • right_entity_id – the right entity id.

classmethod unset_many_to_many(left_entity_id: str, right_entity_id: str)[source]#

For example, in YouTube use case, one playlist has “many” videos. One video can be in “many” playlists. This function will remove the video from the playlist.

Parameters:
  • left_entity_id – the left entity id.

  • right_entity_id – the right entity id.

classmethod find_many_by_many(entity_id: str, lookup_by_left: bool) Iterable[T_BASE_ENTITY][source]#

In many-to-many relationship, for example, “one” Youtube viewer can subscribe “many” Youtube channels, and “one” Youtube channel can be subscribed by “many” Youtube viewers. In this relationship, the viewer is on the left and channel is on the right.

If lookup_by_left is True, this function will find all channels that the given viewer has subscribed. If lookup_by_left is False, this function will find all viewers who have subscribed the given channel.

Parameters:
  • entity_id – the entity id.

  • lookup_by_left – if True, find all items by the left entity id. otherwise, find all items by the right entity id.

classmethod clear_many_by_many(entity_id: str, lookup_by_left: bool)[source]#

Clear all many-to-many relationship items.

Parameters:
  • entity_id – the entity id.

  • lookup_by_left – if True, find all items by the left entity id. otherwise, find all items by the right entity id.

exception DoesNotExist(msg: Optional[str] = None, cause: Optional[Exception] = None)#
class pynamodb_mate.patterns.relationship_v2.impl.BaseEntityIterProxy(iterable: Iterable)[source]#