Skip to content

Refactor entity associations onto betty.attr#4265

Draft
bartfeenstra wants to merge 1 commit into
0.5.xfrom
refactor-associations-onto-attr
Draft

Refactor entity associations onto betty.attr#4265
bartfeenstra wants to merge 1 commit into
0.5.xfrom
refactor-associations-onto-attr

Conversation

@bartfeenstra

@bartfeenstra bartfeenstra commented May 20, 2026

Copy link
Copy Markdown
Owner

This fixes #3581, and #3755, and #2778

To do

  • Now that resolvers no longer work bidirectionally (on purpose, because we could not guarantee order), ensure that GrampsLoader sets inverse associates as well (it never had to). For those cases where a bidirectional association must be populated from unidirectional source data (common in Gramps), add BiResolver which wraps another resolver, and which uses the association to add the owner to the associate's inverse association.
  • Finish data definitions for both association types
  • Finish and test porters for both association types. Use EntityReference.
  • LinkedDataDumpableWithSchemaJsonLdObject.linked_data_schema was updated to always make properties optional as an intermediate solution until this issue is fixed. Ensure properties are set to required depending on their aggregate element definitions.
  • Fix @todos

@bartfeenstra bartfeenstra added this to the 0.5.0 milestone May 20, 2026
@bartfeenstra bartfeenstra added enhancement New feature or request BC break Breaks backwards compatibility with existing integrations python Pull requests that update Python code labels May 20, 2026
@bartfeenstra bartfeenstra force-pushed the refactor-associations-onto-attr branch 2 times, most recently from edefd78 to 6abf3fb Compare May 30, 2026 14:37
@bartfeenstra bartfeenstra force-pushed the refactor-associations-onto-attr branch 2 times, most recently from 07d87cf to 201c028 Compare June 4, 2026 09:36
@bartfeenstra bartfeenstra force-pushed the refactor-associations-onto-attr branch 2 times, most recently from 5c00908 to e438726 Compare June 13, 2026 16:30
Comment thread betty/entity/association.py Outdated
Comment thread betty/entity/association.py Outdated
@bartfeenstra bartfeenstra force-pushed the refactor-associations-onto-attr branch 2 times, most recently from 134c224 to 39e2efb Compare June 14, 2026 13:46
Comment thread betty/datas/optional.py
"""

def __init__(self, wrapped: DataDefinition[DataClsT], /):
try:

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should revert this as the assumption in the data API is that everything is portable, hence the exception and no None return value. We should instead use temporary dummy porters for our associations.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this where entity references come on stage again? Should we move them back into the entity API?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, ideally we add full serialization support now straight away. Probably nota bad idea because there are some issues we haven't thought out yet, e.g. how to resolve/hydrate loaded associations.

@bartfeenstra bartfeenstra force-pushed the refactor-associations-onto-attr branch 2 times, most recently from 0ce4d34 to 14fe0cc Compare June 15, 2026 16:29
Comment thread betty/entity/association.py Outdated


@final
class ToManyAssociates[OwnerT: Entity, AssociateT: Entity](

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to ToManyCollection.


@final
class ToManyAssociates[OwnerT: Entity, AssociateT: Entity](
MutableCollection[AssociateT],

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this a sequence too? Just a regular one, not mutable.

is_entity = isinstance(associate, Entity)
if not is_entity:
self._resolved = False
elif associate in tuple(

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this check outside the loop.


def add(self, *associates: Associate[OwnerT, AssociateT]) -> None:
"""
Add the given associate.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plural


def __init__(
self,
associate_type_name: str,

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow types as well as names.


def __init__(
self,
associate_type_name: str,

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow types as well as names.

location: ResolvableLocalizable | None = None,
date: AnyDate | None = None,
file_references: ToManyAssociates[FileReference] = (),
file_references: Iterable[Associate[Self, FileReference]] = (),

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ToManyAssociates again

Comment thread betty/entities/event.py
id: str | None = None, # noqa: A002
event_type: EventType | None = None,
date: AnyDate | None = None,
file_references: ToManyAssociates[FileReference] = (),

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a separate PR, rename HasFileReferences.file_references to .files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BC break Breaks backwards compatibility with existing integrations enhancement New feature or request python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor entity associations onto betty.collections Refactor entity associations onto betty.attr To-many entity resolvers do not persist order

1 participant