tortoise / tortoise/tortoise-orm
Unexpected call to `to_python_value` when creating new "Model"
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 516
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 9
Description
Describe the bug
Models needs to take in db value when creating model instead of pythonic value.
To Reproduce
import traceback
from typing import List
from tortoise import Model, Tortoise, run_async
from tortoise.fields import TextField
class TextListField(TextField):
__SEPERATOR = ", "
def __init__(self, **kwargs):
super().__init__(**kwargs)
def to_db_value(self, value: List[str], instance) -> str:
print(f"`to_db_value` provided value type is {type(value)}")
return self.__SEPERATOR.join(value)
def to_python_value(self, value: str) -> List[str]:
print(f"`to_python_value` provided value type is {type(value)}")
return value.split(self.__SEPERATOR)
class Test(Model):
list = TextListField()
async def init():
await Tortoise.init(
db_url='sqlite://db.sqlite3',
modules={'models': ['__main__']}
)
await Tortoise.generate_schemas()
try:
await Test.create(list=["a", "b"])
except AttributeError:
data = traceback.format_exc()
print(data)
await Test.create(list="a, b")
if __name__ == '__main__':
run_async(init())
Output for first create:
`to_python_value` provided value type is <class 'list'>
Traceback (most recent call last):
File "E:\Codes\main.py", line 36, in make_test_with_list
await Test.create(list=["a", "b"])
File "E:\Codes\venv\lib\site-packages\tortoise\models.py", line 1132, in create
instance = cls(**kwargs)
File "E:\Codes\venv\lib\site-packages\tortoise\models.py", line 671, in __init__
for key in meta.fields.difference(self._set_kwargs(kwargs)):
File "E:\Codes\venv\lib\site-packages\tortoise\models.py", line 698, in _set_kwargs
setattr(self, key, field_object.to_python_value(value))
File "E:\Codes\main.py", line 20, in to_python_value
return value.split(self.__SEPERATOR)
AttributeError: 'list' object has no attribute 'split'
Output for second create:
`to_python_value` provided value type is <class 'str'>
`to_db_value` provided value type is <class 'list'>
Process finished with exit code 0
Expected behavior
My expectation is that in the first create shouldn't fail
Additional context
In my opinion the call to to_python_value isn't supposed to happen.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in tortoise/models.py at Model.init and _set_kwargs, where the traceback shows to_python_value being called during model creation. Reproduce the two Test.create cases from the issue and trace the field-value flow. Done means the first create no longer fails while the existing database conversion behavior remains correct.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100