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

Optional EmbeddedModel not working #370

Open
carlosfrutos opened this issue Oct 5, 2023 · 3 comments
Open

Optional EmbeddedModel not working #370

carlosfrutos opened this issue Oct 5, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@carlosfrutos
Copy link

carlosfrutos commented Oct 5, 2023

Bug

Somehow related to #350 with both situations I faced and I couldn't solve.

import traceback

from odmantic import Model, EmbeddedModel, Field
from typing import Optional


class Error(EmbeddedModel):
    code: int = Field(500)
    message: str = Field("Internal Server Error")


class Document(Model):
    text: str = Field(...)
    error: Optional[Error]

try:
    print(Document(text="This is a test", error=None).doc())
except Exception as e:
    print(traceback.format_exc())
try:
    print(Document(text="This is a failure", error=Error(code=404, message="Not found")).doc())
except Exception as e:
    print(traceback.format_exc())

Current Behavior

Raises Exception in both cases. Happens in all versions starting from 0.9.0

Traceback (most recent call last):
  File "[...]\odmantic_error.py", line 17, in <module>
    print(Document(text="This is a test", error=None).doc())
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 745, in doc
    doc = self.__doc(raw_doc, type(self), include)
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 715, in __doc
    doc[field.key_name] = [
TypeError: 'NoneType' object is not iterable

Traceback (most recent call last):
  File "[...]\odmantic_error.py", line 21, in <module>
    print(Document(text="This is a failure", error=Error(code=404, message="Not found")).doc())
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 745, in doc
    doc = self.__doc(raw_doc, type(self), include)
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 715, in __doc
    doc[field.key_name] = [
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 716, in <listcomp>
    self.__doc(item, field.model) for item in raw_doc[field_name]
  File "[...]-py3.9\lib\site-packages\odmantic\model.py", line 723, in __doc
    doc[field.key_name] = raw_doc[field_name]
TypeError: string indices must be integers

Expected behavior

It should create the document, regardless "error" has a valid value or is None. This was working in version 0.8.0. It stopped working from 0.9.0 and keeps happening in 0.9.2.

{'text': 'This is a test', 'error': None, '_id': ObjectId('651ef586b2624498484fbd22')}
{'text': 'This is a failure', 'error': {'code': 404, 'message': 'Not found'}, '_id': ObjectId('651ef586b2624498484fbd23')}

Environment

  • ODMantic version: 0.9.0
  • MongoDB version: N/A
  • Pydantic infos (output of python -c "import pydantic.utils; print(pydantic.utils.version_info())):
             pydantic version: 1.10.7
            pydantic compiled: True
                 install path: [...]
               python version: 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)]
                     platform: Windows-10-10.0.22621-SP0
     optional deps. installed: ['dotenv', 'typing-extensions']

@carlosfrutos carlosfrutos added the bug Something isn't working label Oct 5, 2023
@renja-g
Copy link

renja-g commented Mar 14, 2024

@carlosfrutos Did you find a way to work around?
Also, @art049 are there any plans to fix this, because this issue is already quite old

I currently have the same problem:

class miniSeriesDTO(EmbeddedModel):
    losses: int
    progress: str
    target: int
    wins: int


class LeagueEntry(Model):
    leagueId: str
    queueType: str
    tier: TierEnum
    rank: RankEnum
    leaguePoints: int
    wins: int
    losses: int
    hotStreak: bool
    veteran: bool
    freshBlood: bool
    inactive: bool
    miniSeries: Optional[miniSeriesDTO] = None

@conql
Copy link

conql commented Apr 7, 2024

Are there any updates or workarounds?

@carlosfrutos
Copy link
Author

carlosfrutos commented Apr 16, 2024

@renja-g
I ended up using an array. If it's empty, then I consider it equivalent as None. Key names are ignored though:

import traceback
from typing import List

from odmantic import Model, EmbeddedModel, Field, Reference


class Error(EmbeddedModel):
    code: int = Field(500)
    message: str = Field("Internal Server Error")


class Document(Model):
    text: str = Field(...)
    error: List[Error] = Reference(key_name="dsError")

try:
    print(Document(text="This is a test", error=[]).doc())
except Exception as e:
    print(traceback.format_exc())
try:
    print(Document(text="This is a failure", error=[Error(code=404, message="Not found")]).doc())
except Exception as e:
    print(traceback.format_exc())

Output:

{'text': 'This is a test', 'error': [], '_id': ObjectId('661e929c48b2346427e89de1')}
{'text': 'This is a failure', 'error': [{'code': 404, 'message': 'Not found'}], '_id': ObjectId('661e929c48b2346427e89de2')}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants