4

I am trying to structure the code for my data model using pydantic but I am running into an apparently insolvable problem.

The code below works as expected:

main.py

#
from __future__ import annotations
#
from pydantic import BaseModel
#
class Item(BaseModel):
    tag: Tag = None
    class Config:
        orm_mode = True

class Tag(BaseModel):
    item: Item = None
    class Config:
        orm_mode = True


Item.update_forward_refs()
Tag.update_forward_refs()

i = Item()
t = Tag()

i.tag = t
t.item = i
# print(i) fails due to cyclic model but this is another story

Then I am trying to refactor my code like this:

main.py
model/item.py
model/tag.py

with

main.py:

#
from model.item import Item
from model.tag import Tag
#
Item.update_forward_refs()
Tag.update_forward_refs()
#
i = Item()
t = Tag()
#
i.tag = t
t.item = i

model/item.py:

#
from __future__ import annotations
#
from pydantic import BaseModel
#
from .tag import Tag
#
class Item(BaseModel):
    tag: Tag = None
    class Config:
        orm_mode = True

model/tag.py:

#
from __future__ import annotations
#
from pydantic import BaseModel
#
from .item import Item
#
class Tag(BaseModel):
    item: Item = None
    class Config:
        orm_mode = True

This code fails on import because of the cross reference of tag to item and vice versa. But if I remove the imports from the model files:


    from .item import Item

    from .tag import Tag

The code fails again complaining about missing Tag or Item:

NameError: name 'Tag' is not defined 
NameError: name 'Item' is not defined 

All other attempts failed, like using explicit reference model.Item instead of Item.

What is the correct way to get around this, preferably keeping the nice symmetry of the code ?

MeMeMe
  • 51
  • 4
  • Why would you need such a cross dependency in the first place? It's dead wrong to have such a cross reference in a database. Are you sure the relationship isn't Item<-Tag? – lsabi Sep 02 '20 at 11:26
  • Well, cross dependency is a very natural thing in data modelling and very handy as well. There is no intrinsic problem to code that with any modern ORM either... I do not think this is 'dead wrong' although it indeed requires additional efforts to maintain integrity in a DB. – MeMeMe Sep 02 '20 at 16:59
  • 1
    I can only judge what I can see and I would find another way of modelling it. Anyway, the straight solution is to put both classes together in the same file. Otherwise, you could specify a dictionary instead of tag/item and validate it by importing the tag/item class and creating an instance of it – lsabi Sep 02 '20 at 21:35

0 Answers0