tortoise-orm
tortoise-orm copied to clipboard
ReverseRelation["Model"]
Hi all, for Tortoise-ORM how can add the ReverseRelation["Model"] in a multiple file setup without a circular import problem?
from typing import TYPE_CHECKING
if TYPE_CHECKING:
# import ...
from typing import TYPE_CHECKING if TYPE_CHECKING: # import ...
I've tried this still getting an error.
NameError: name 'Model' is not defined
Could you show full code?
models/devices.py
from typing import TYPE_CHECKING
from tortoise import Tortoise, fields
from tortoise.contrib.pydantic import pydantic_model_creator
from tortoise.models import Model
from models.staff import StaffAccount
from models.relations import resolve_relationships
if TYPE_CHECKING:
from models.customers import CustomerLogin
class DeviceClassification(Model):
device_token = fields.UUIDField(unique=True)
classification = fields.CharField(30)
valid_from = fields.DatetimeField()
valid_to = fields.DatetimeField(null=True)
note = fields.TextField(null=True)
customer_login: fields.ReverseRelation['CustomerLogin']
resolve_relationships()
DeviceClassification_Pydantic = pydantic_model_creator(DeviceClassification)
DeviceClassification_PydanticIn = pydantic_model_creator(DeviceClassification, exclude_readonly=True)
models/customers.py
from tortoise import fields
from tortoise.contrib.pydantic import pydantic_model_creator
from tortoise.models import Model
from models.events import ShardID, SequenceNum
from models.users import UserID
from models.devices import DeviceClassification
from models.relations import resolve_relationships
class CustomerLogin(Model):
device_token: fields.ForeignKeyNullableRelation[DeviceClassification] = \
fields.ForeignKeyField(model_name='models.DeviceClassification',
related_name='customerlogin_deviceclass',
to_field='device_token',
on_delete=fields.RESTRICT,
null=True)
event_timedate = fields.DatetimeField(null=True)
user_ip = fields.CharField(256, null=True)
user_agent = fields.CharField(1024, null=True)
client_id = fields.CharField(256, null=True)
process = fields.CharField(256, null=True)
auth_result = fields.CharField(256, null=True)
auth_fail_cause = fields.CharField(256, null=True)
plain_email = fields.CharField(256, null=True)
resolve_relationships()
CustomerLogin_Pydantic = pydantic_model_creator(CustomerLogin, name='CustomerLogin')
CustomerLogin_PydanticIn = pydantic_model_creator(CustomerLogin, name='CustomerLoginIn', exclude_readonly=True)
models/relations.py
from tortoise import Tortoise
model_list = [
'models.customers',
'models.devices',
]
def resolve_relationships() -> None:
Tortoise.init_models(model_list, "models")
I am getting this error:
NameError: name 'CustomerLogin' is not defined
I faced the same issue of circular imports
The only two solutions that I found were:
- Club both
CustomerLogin
andDeviceClassification
into a single file - Remove the reverse relation
customer_login: fields.ReverseRelation['CustomerLogin']
fromDeviceClassification
Also, I was wondering why do you call resolve_relationships()
twice? @joweenflores
I faced the same issue of
circular imports
The only two solutions that I found were:
- Club both
CustomerLogin
andDeviceClassification
into a single file- Remove the reverse relation
customer_login: fields.ReverseRelation['CustomerLogin']
fromDeviceClassification
Also, I was wondering why do you call
resolve_relationships()
twice? @joweenflores
is there really no solution on this with multiple files?
I faced the same issue of
circular imports
The only two solutions that I found were:
- Club both
CustomerLogin
andDeviceClassification
into a single file- Remove the reverse relation
customer_login: fields.ReverseRelation['CustomerLogin']
fromDeviceClassification
Also, I was wondering why do you call
resolve_relationships()
twice? @joweenfloresis there really no solution on this with multiple files?
Is there any other possible solution? Please help us @grigi @long2ice
+1 here, using aerich with type hinting is an absolute mess as well
+1 here, using aerich with type hinting is an absolute mess as well
not work ,the same problem
I came up with a dirty-patching solution:
from __future__ import annotations
class DeviceClassification(Model):
...
customer_login: fields.ReverseRelation['CustomerLogin']
...
from models.customers import CustomerLogin # import at end of file
Doesn't seem that nice, but it works at least.
@SnowSuno what python version are you using? I'm using 3.10
and getting NameError: name <...> is not defined
@SnowSuno what python version are you using? I'm using
3.10
and gettingNameError: name <...> is not defined
I'm using 3.9
and 3.10
.
In 3.10
, it should work even without adding
from __future__ import annotations
since it is supported in default in version 3.10
and above.
c.f.
In my case, the NameError
I was getting was raised by pydantic_model_creator
and was solved by the solution above, which might not be the case in yours.
@SnowSuno FYI in 3.10
version that import feature got delayed. So it probably will be in 3.11
I have the same problem, models in multiple files, and thanks to the information above I resolve the issue put from __future__ import annotations
. With this, I could use fields.ReverseRelation
. I'm using python 3.8.10
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
...
The above snippet works in Python 3.10.12
Any solution for Python 3.11.6? None of the above works