Skip to content

Conversation

AurelienJaquier
Copy link
Contributor

I made it so the ValidationResult entities that point to an MEModel show up in the MEModelRead.
I am not sure if the code is good quality, but I tested it locally and it was working

@AurelienJaquier AurelienJaquier self-assigned this May 22, 2025
app/db/model.py Outdated
@@ -303,6 +303,74 @@ def etypes(cls) -> Mapped[list["ETypeClass"]]:
)


class Entity(LegacyMixin, Identifiable):
Copy link
Collaborator

Choose a reason for hiding this comment

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

it would be helpful if the class Entity wasn't moved around, so the diff is smaller, and it makes it easier to see the changes, could you move it back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, I moved it back

@@ -59,3 +60,4 @@ class MEModelRead(
etypes: list[ETypeClassRead] | None
morphology: ReconstructionMorphologyRead
emodel: EModelRead
validation_results: list[ValidationResultRead] | None = None
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a discussion ongoing on the other PR on how to handle nested resources:

#183

Depending on what's decided there we would potentially remove this field and instead have a
/validation_results endpoint with a memodel_id__in filter.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it should be fine to add it to the list view, there are only a few validations per me_model and they only contain 1 asset is that right @AurelienJaquier ?

What do you think @eleftherioszisis ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, fine by me!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As of now, an me-model should have up to 7 ValidationResults, and each ValidationResult can contain 2 to 3 assets (1 or 2 figures, and a validation_details.txt giving additional information about the run of the validation).

Copy link
Contributor

@g-bar g-bar May 27, 2025

Choose a reason for hiding this comment

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

Actually @AurelienJaquier

The response is already quite hefty, look at all those joins.
And we already have a /validation_results enpoint which is filterable by validated_entity_id that's all the frontend needs.

Unless you need the validation results in batch, I suggest we use the endpoint above instead of nesting the data here.

 return select.options(
        joinedload(MEModel.species),
        joinedload(MEModel.strain),
        joinedload(MEModel.emodel).options(
            joinedload(EModel.species),
            joinedload(EModel.strain),
            joinedload(EModel.exemplar_morphology),
            joinedload(EModel.brain_region),
            selectinload(EModel.contributions).joinedload(Contribution.agent),
            selectinload(EModel.contributions).joinedload(Contribution.role),
            joinedload(EModel.mtypes),
            joinedload(EModel.etypes),
            joinedload(EModel.created_by),
            joinedload(EModel.updated_by),
            selectinload(EModel.assets),
        ),
        joinedload(MEModel.morphology).options(
            joinedload(ReconstructionMorphology.brain_region),
            selectinload(ReconstructionMorphology.contributions).selectinload(Contribution.agent),
            selectinload(ReconstructionMorphology.contributions).selectinload(Contribution.role),
            joinedload(ReconstructionMorphology.mtypes),
            joinedload(ReconstructionMorphology.license),
            joinedload(ReconstructionMorphology.species),
            joinedload(ReconstructionMorphology.strain),
            joinedload(ReconstructionMorphology.created_by),
            joinedload(ReconstructionMorphology.updated_by),
            selectinload(ReconstructionMorphology.assets),
        ),
        joinedload(MEModel.brain_region),
        selectinload(MEModel.contributions).joinedload(Contribution.agent),
        selectinload(MEModel.contributions).joinedload(Contribution.role),
        joinedload(MEModel.mtypes),
        joinedload(MEModel.etypes),
        joinedload(MEModel.created_by),
        joinedload(MEModel.updated_by),
        selectinload(MEModel.validation_results),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, then I will close this PR, and just use entitysdk to search directly ValidationResult with filtering by validated_entity_id.

app/db/model.py Outdated
"ValidationResult",
primaryjoin=f"foreign(ValidationResult.validated_entity_id) == {cls.__name__}.id",
foreign_keys="[ValidationResult.validated_entity_id]",
cascade="all, delete-orphan",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think delete-orphan is not necessary delete only works. Since the validated_entity_id is not nullable orphans are impossible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, done in latest commit

app/db/model.py Outdated
primaryjoin=f"foreign(ValidationResult.validated_entity_id) == {cls.__name__}.id",
foreign_keys="[ValidationResult.validated_entity_id]",
cascade="all, delete-orphan",
lazy="dynamic", # or "select", as needed
Copy link
Contributor

@g-bar g-bar May 27, 2025

Choose a reason for hiding this comment

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

I think we want 'selectin' in case we want to fetch the validation results of multiple entities at once.

But in general we're not using this we're defining the eager loading function manually here:

def _load(select: Select):

I'm surprised this passes the tests it should raise an exception because of the raiseload("*"),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the lazy key, and added selectinload(MEModel.validation_results) in _load in latest commit

msg = f"{cls} should be an Entity"
raise TypeError(msg)

return relationship(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should pass uselist=True

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, done in latest commit

@@ -59,3 +60,4 @@ class MEModelRead(
etypes: list[ETypeClassRead] | None
morphology: ReconstructionMorphologyRead
emodel: EModelRead
validation_results: list[ValidationResultRead] | None = None
Copy link
Contributor

@g-bar g-bar May 27, 2025

Choose a reason for hiding this comment

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

validation_results: list[ValidationResultRead] | None = N one

None is not a possible value, if there are no validation results sqlalchemy will return an empty list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I turned this line into validation_results: list[ValidationResultRead] = [] in latest commit

@AurelienJaquier AurelienJaquier deleted the memodelread-validationresult branch May 27, 2025 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants