tortoise / tortoise/tortoise-orm
Pydantic serialisation of relations not works
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
Get TypeError: sequence item 0: expected str instance, int found when trying do PydanticModel.from_tortoise_orm(orm_instance).
File "/usr/local/lib/python3.8/site-packages/tortoise/contrib/pydantic/base.py", line 86, in from_tortoise_orm
backend_1 | await obj.fetch_related(*fetch_fields)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/models.py", line 932, in fetch_related
backend_1 | await db.executor_class(model=self.class, db=db).fetch_for_list([self], *args)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 559, in fetch_for_list
backend_1 | await self._execute_prefetch_queries(instance_list)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 536, in _execute_prefetch_queries
backend_1 | await asyncio.gather(*prefetch_tasks)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 525, in _do_prefetch
backend_1 | return await self._prefetch_direct_relation(instance_id_list, field, related_query)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 486, in _prefetch_direct_relation
backend_1 | related_object_list = await related_query.filter(
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/queryset.py", line 803, in _execute
backend_1 | instance_list = await self._db.executor_class(
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 123, in execute_select
backend_1 | _, raw_results = await self.db.execute_query(query.get_sql())
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/dialects.py", line 507, in get_sql
backend_1 | querystring = super(PostgreQueryBuilder, self).get_sql(with_alias, subquery, **kwargs)
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/queries.py", line 1267, in get_sql
backend_1 | querystring += self._where_sql(**kwargs)
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/queries.py", line 1394, in _where_sql
backend_1 | return " WHERE {where}".format(where=self._wheres.get_sql(quote_char=quote_char, subquery=True, **kwargs))
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/terms.py", line 776, in get_sql
backend_1 | container=self.container.get_sql(subquery=True, **kwargs),
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/terms.py", line 585, in get_sql
backend_1 | sql = "({})".format(",".join(term.get_sql(**kwargs) for term in self.values))
backend_1 | TypeError: sequence item 0: expected str instance, int found
backend_1 | ERROR:uvicorn.error:Exception in ASGI application
backend_1 | Traceback (most recent call last):
backend_1 | File "/usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 390, in run_asgi
backend_1 | result = await app(self.scope, self.receive, self.send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in call
backend_1 | return await self.app(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/fastapi/applications.py", line 146, in call
backend_1 | await super().call(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/applications.py", line 102, in call
backend_1 | await self.middleware_stack(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 181, in call
backend_1 | raise exc from None
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 159, in call
backend_1 | await self.app(scope, receive, _send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/middleware/cors.py", line 76, in call
backend_1 | await self.app(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 82, in call
backend_1 | raise exc from None
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 71, in call
backend_1 | await self.app(scope, receive, sender)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 550, in call
backend_1 | await route.handle(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 227, in handle
backend_1 | await self.app(scope, receive, send)
backend_1 | File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 41, in app
backend_1 | response = await func(request)
backend_1 | File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 196, in app
backend_1 | raw_response = await run_endpoint_function(
backend_1 | File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 148, in run_endpoint_function
backend_1 | return await dependant.call(**values)
backend_1 | File "./app/router/register.py", line 27, in register
backend_1 | return await User_Pydantic.from_tortoise_orm(created_user)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/contrib/pydantic/base.py", line 86, in from_tortoise_orm
backend_1 | await obj.fetch_related(*fetch_fields)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/models.py", line 932, in fetch_related
backend_1 | await db.executor_class(model=self.class, db=db).fetch_for_list([self], *args)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 559, in fetch_for_list
backend_1 | await self._execute_prefetch_queries(instance_list)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 536, in _execute_prefetch_queries
backend_1 | await asyncio.gather(*prefetch_tasks)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 525, in _do_prefetch
backend_1 | return await self._prefetch_direct_relation(instance_id_list, field, related_query)
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 486, in _prefetch_direct_relation
backend_1 | related_object_list = await related_query.filter(
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/queryset.py", line 803, in _execute
backend_1 | instance_list = await self._db.executor_class(
backend_1 | File "/usr/local/lib/python3.8/site-packages/tortoise/backends/base/executor.py", line 123, in execute_select
backend_1 | _, raw_results = await self.db.execute_query(query.get_sql())
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/dialects.py", line 507, in get_sql
backend_1 | querystring = super(PostgreQueryBuilder, self).get_sql(with_alias, subquery, **kwargs)
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/queries.py", line 1267, in get_sql
backend_1 | querystring += self._where_sql(**kwargs)
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/queries.py", line 1394, in _where_sql
backend_1 | return " WHERE {where}".format(where=self._wheres.get_sql(quote_char=quote_char, subquery=True, **kwargs))
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/terms.py", line 776, in get_sql
backend_1 | container=self.container.get_sql(subquery=True, **kwargs),
backend_1 | File "/usr/local/lib/python3.8/site-packages/pypika/terms.py", line 585, in get_sql
backend_1 | sql = "({})".format(",".join(term.get_sql(**kwargs) for term in self.values))
backend_1 | TypeError: sequence item 0: expected str instance, int found
To Reproduce
- Create model A
- Create model B with one relation to model A
- Tortoise.init_models(['app.models'], 'models')
- B_Pydantic = pydantic_model_creator(B)
- await B_Pydantic.from_tortoise_orm(b_instance)
Expected behavior
get related data without errors
Additional context
Add any other context about the problem here.
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
Reproduce the two-model relation case described in the issue, then trace from tortoise/contrib/pydantic/base.py through models.py and backends/base/executor.py to the failing query generation in pypika/terms.py. Confirm that B_Pydantic.from_tortoise_orm(b_instance) fetches related data without the TypeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100