Handle references within generics of EmbeddedModel
- Dominant language
- Python
- Stars
- 1.2k
- Forks
- 97
- PR merge metrics
- No merged PRs in 30d
Description
# Bug
When i try to reference other model in EmbeddedModel, i get full document inserted instead of reference to it
### Current Behavior
I have these models:
```python
class Need(Model):
name: str
class PetNeed(EmbeddedModel):
need: Need = Reference()
value: int = Field(default=0)
class Pet(Model):
name: str
needs: List[PetNeed] = Field(default=[])
```
If i try to do this:
```python
hunger = Need(name='Hunger')
dog = Pet(name='Dog')
dog.needs.append(PetNeed(need=hunger))
await engine.save_all([hunger, dog])
```
I get this in the database:
```
{
"_id": {
"$oid": "60062e817a596be396df8ab8"
},
"name": "Dog",
"needs": [{
"need": {
"name": "Hunger",
"id": {
"$oid": "60062e817a596be396df8ab7"
}
},
"value": 0
}]
}
```
As you can see full model being inserted into the database with both name and id instead of just reference id to it
However everything is fine if i reference Need model directly:
```python
rest = Need(name='Rest')
cat = Pet(name='Cat', need=rest)
await engine.save_all([rest, cat])
```
Database:
```
{
"_id": {
"$oid": "6006326f0092a86615eeae91"
},
"name": "Cat",
"need": {
"$oid": "6006326f0092a86615eeae90"
}
}
```
### Expected behavior
ODMantic should put reference id in EmbeddedModel instead of putting full Model in the field
### Environment
- ODMantic version: 0.3.2
- MongoDB version: 4.2.11
- Pydantic infos (output of `python -c "import pydantic.utils; print(pydantic.utils.version_info())`):
```
pydantic version: 1.7.3
pydantic compiled: True
install path: D:\_Projects\python\bot\py\Lib\site-packages\pydantic
python version: 3.9.1 (tags/v3.9.1:1e5d33e, Dec 7 2020, 17:08:21) [MSC v.1927 64 bit (AMD64)]
platform: Windows-10-10.0.18362-SP0
optional deps. installed: ['typing-extensions']
```
**Additional context**
It is also impossible to make reference fields `Optional` or put them in a `List`, but I read in the docs that it is planned to make a generic `Reference[T]` type so it's ok
Contributor guide
Research direction
Start by reproducing the issue with the Need, PetNeed, and Pet models shown, then trace how references inside EmbeddedModel fields are serialized during engine.save_all. Done means the embedded need stores only the referenced model's id, while direct references continue to work and the reported generic cases are covered by regression tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- mongodb, python
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100