Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

schema checks and unit tests. #3

Conversation

WaVEV
Copy link
Collaborator

@WaVEV WaVEV commented Dec 7, 2024

I added the schema checks in get_transform, I didn't find any other place to put it.

The code got a bit dirty if we use embedded field with jsonfield. This use case is strange but possible.
I couldn't find any other way to do this task without breaking JSON.

django_mongodb/compiler.py Outdated Show resolved Hide resolved
@timgraham timgraham force-pushed the embedded-model-field branch from e2947b8 to dd65bb7 Compare December 13, 2024 20:32
@WaVEV WaVEV force-pushed the embedded-model-field-schema-checks branch from a752b20 to 9a8ffd5 Compare December 16, 2024 00:15
Copy link
Owner

@timgraham timgraham left a comment

Choose a reason for hiding this comment

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

Sorry for the delay in looking at this. Let's focus on the field validation (first commit) and move the querying bits to another PR.

tests/model_fields_/test_embedded_model.py Outdated Show resolved Hide resolved
tests/model_fields_/models.py Show resolved Hide resolved
django_mongodb/fields/embedded_model.py Outdated Show resolved Hide resolved
@WaVEV WaVEV force-pushed the embedded-model-field-schema-checks branch from bf71f56 to 86ac26a Compare December 30, 2024 02:40
@WaVEV
Copy link
Collaborator Author

WaVEV commented Dec 30, 2024

Sorry for the delay in looking at this. Let's focus on the field validation (first commit) and move the querying bits to another PR.

I reorder the commits to have the first 5 for validation and the other 2 for testing.

@WaVEV WaVEV force-pushed the embedded-model-field-schema-checks branch from 86ac26a to 2d75b39 Compare December 30, 2024 03:07
@timgraham timgraham force-pushed the embedded-model-field branch from dd65bb7 to 62cafa8 Compare December 30, 2024 18:57
@WaVEV WaVEV force-pushed the embedded-model-field-schema-checks branch from 2d75b39 to 4da45f2 Compare December 30, 2024 19:05
@timgraham
Copy link
Owner

I rebased embedded-model-field branch on main, so if you rebase your branch on that, it should fix the issue.

@WaVEV WaVEV force-pushed the embedded-model-field-schema-checks branch from 4da45f2 to d6f7812 Compare December 30, 2024 23:42
@timgraham
Copy link
Owner

Refresh my memory... we can't support foreign key because of the double underscore lookup syntax collision, correct? In that case, I'm wondering if we'll need to revisit how we do querying in order to allow foreign key (even if it's a future task) in embedded documents. (I'm not sure whether or not we need to support it... have to check with Jib + team.)

@WaVEV
Copy link
Collaborator Author

WaVEV commented Dec 31, 2024

Refresh my memory... we can't support foreign key because of the double underscore lookup syntax collision, correct? In that case, I'm wondering if we'll need to revisit how we do querying in order to allow foreign key (even if it's a future task) in embedded documents. (I'm not sure whether or not we need to support it... have to check with Jib + team.)

🤔 Yes, the problem is when Django interprets the query. The setup_joins function handles it, but it always treats the __ as joins (if it’s not a lookup). So, if a join comes before a path query into the embedded field, it works, but not the reverse (a join using an embedded field's field) because a different flow handles the query interpretation. If we want to support this kind of behavior, we should treat the embedded fields as fake-joins.

I don’t know if we can define a foreign key as a field in a JSONField. I don’t think so, but if it’s possible, we should take a look.

@timgraham
Copy link
Owner

No foreign key in JSON. It's always just "data."

See Djongo's EmbeddedField API for an alternate query syntax we could consider.

@WaVEV
Copy link
Collaborator Author

WaVEV commented Dec 31, 2024

No foreign key in JSON. It's always just "data."

See Djongo's EmbeddedField API for an alternate query syntax we could consider.

🤔 This changes things a bit, I didn’t know this kind of syntax existed 😬. I have two questions:

In Django, filtering usually works with an argument structured as column_field + lookup, and the value is just the value to filter by. But here, we have a mixed approach where the value part includes both field + value, while the argument name is embedded_field + lookup. Is that correct?
The tests I wrote are based on the other format, so they’re not valid for this one.
Also, even though I don’t know how to implement a foreign field inside an embedded field, how would this syntax support such queries? I can think of two possible options:

entries = Entry.objects.filter(embedded_field__foreign_field__name__startswith={'name': 'Beatles'})
entries = Entry.objects.filter(embedded_field__startswith={'foreign_field__name': 'Beatles'})
Which one (if either) would we use?

@Jibola
Copy link

Jibola commented Jan 3, 2025

Refresh my memory... we can't support foreign key because of the double underscore lookup syntax collision, correct? In that case, I'm wondering if we'll need to revisit how we do querying in order to allow foreign key (even if it's a future task) in embedded documents. (I'm not sure whether or not we need to support it... have to check with Jib + team.)

I don't think it needs to be supported as I'd rather we remove any opportunities to promote the ForeignKey field usage; however, having a task to investigate its work sounds just fine to me.

@Jibola
Copy link

Jibola commented Jan 3, 2025

I added the schema checks in get_transform, I didn't find any other place to put it.

The code got a bit dirty if we use embedded field with jsonfield.

What would be a use-case you'd imagine? If someone is using an EmbeddedModel in a JSONField that feels counterintuitive.

I'm all for not supporting this usecase if it's too much work; work has already been done to support it, but if it's creating complications, you can take out the requirement. If someone is using EmbeddedField with JSONField, I'm hard-pressed to understand if that's worthwhile.

Copy link

@Jibola Jibola left a comment

Choose a reason for hiding this comment

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

Added some comments. I haven't reviewed all the test cases yet, but will come back to it today. :)

django_mongodb/fields/embedded_model.py Show resolved Hide resolved
Comment on lines 152 to 154
msg = "Address has no field named 'president'"
with self.assertRaisesMessage(FieldDoesNotExist, msg):
Book.objects.filter(author__address__city__president="NYC")
Copy link

Choose a reason for hiding this comment

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

shouldn't this be city has no field name president? or address has no field named city.president?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

🤔 I think you are right. I will check this out.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I used "Address.city has no field named 'president'" if you don't like it, let me know is a easy change

Copy link
Owner

Choose a reason for hiding this comment

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

It could be a mistyped field OR transform, so the message should reflect that. It would be neat to replicate the logic here which could offer suggestions for similar lookups AND fields.
https://github.com/django/django/blob/40d5516385448a73426aad396778f369a363eda9/django/db/models/sql/query.py#L1440-L1452

@WaVEV
Copy link
Collaborator Author

WaVEV commented Jan 4, 2025

I added the schema checks in get_transform, I didn't find any other place to put it.
The code got a bit dirty if we use embedded field with jsonfield.

What would be a use-case you'd imagine? If someone is using an EmbeddedModel in a JSONField that feels counterintuitive.

I'm all for not supporting this usecase if it's too much work; work has already been done to support it, but if it's creating complications, you can take out the requirement. If someone is using EmbeddedField with JSONField, I'm hard-pressed to understand if that's worthwhile.

I agree, the use case is unusual, and maybe we should suggest avoiding it. But as long as the embedded fields are fully typed, the user might have a reason for wanting semi-structured data inside embedded field.

@timgraham timgraham force-pushed the embedded-model-field branch from 62cafa8 to b61cf56 Compare January 6, 2025 22:27
@timgraham timgraham force-pushed the embedded-model-field branch 7 times, most recently from aed181d to 07525fe Compare January 14, 2025 00:21
@timgraham timgraham force-pushed the embedded-model-field branch from e522e32 to f77e03c Compare January 14, 2025 12:55
@timgraham
Copy link
Owner

This work has been integrated in PRs to the main repo.

@timgraham timgraham closed this Jan 31, 2025
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.

3 participants