TypeError: issubclass() arg 1 must be a class when inheriting BaseModel of a class with a complex type #949
-
First Check
Commit to Help
Example Codeclass File(BaseModel):
name: str
url: str
class Producer(BaseModel):
. . .
files: Optional[List[File]]
class FileSQL(SQLModel, File, table=True):
. . .
producer: Optional["ProducerSQL"] = Relationship(back_populates="files")
class ProducerSQL(SQLModel, Producer, table=True):
. . .
files: Optional[List[FileSQL]] = Relationship(back_populates="producer") DescriptionWhen attempting to define a relationship between two models (ProducerSQL and FileSQL) using SQLModel, an error is raised if the base model (Producer) contains a field of type Optional[List[File]]. The error does not occur if this field is removed. Actual BehaviorTraceback (most recent call last):
File "<module>", line 83, in <module>
class ProducerSQL(SQLModel, Producer, table=True):
File "<virtualenv>/lib/python3.11/site-packages/sqlmodel/main.py", line 482, in __new__
col = get_column_from_field(v)
^^^^^^^^^^^^^^^^^^^^^^^^
File "<virtualenv>/lib/python3.11/site-packages/sqlmodel/main.py", line 626, in get_column_from_field
sa_type = get_sqlalchemy_type(field)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<virtualenv>/lib/python3.11/site-packages/sqlmodel/main.py", line 575, in get_sqlalchemy_type
if issubclass(type_, Enum):
^^^^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class Temporary solutionI obviously took out another intermediate model (fortunately, this one fit into my pipeline) and implemented the following method: @staticmethod
def prepare_to_db(item: ProducerLoader) -> ProducerSQL:
files = [FileSQL(**file.dict()) for file in item.files]
delattr(item, "files")
sql_model = ProducerSQL(**item.dict())
sql_model.files = files
return sql_model It's dirty, but working Operating SystemLinux Operating System DetailsUbuntu 22.04.4 LTS SQLModel Version0.0.18 Python Version3.11 Additional Contextpydantic = 2.7.1 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
What I would suggest is to stay away from Remember that SQLModel is a wrapper around Pydantic and SQLAlechemy. So behind the scenes, the For the most part (at least in your example above), inheriting from The fix I would suggest would be to always inherit from This would also remove your multiple inheritance pattern like from typing import List, Optional
from sqlmodel import SQLModel
class File(SQLModel): # table=False by default
name: str
url: str
class Producer(SQLModel):
...
files: Optional[List[File]]
class FileSQL(File, table=True): # `File` itself inherits from SQLModel
...
producer: Optional["ProducerSQL"] = Relationship(back_populates="files")
class ProducerSQL(Producer, table=True): # `Producer` itself inherits from SQLModel
...
files: Optional[List[FileSQL]] = Relationship(back_populates="producer") |
Beta Was this translation helpful? Give feedback.
-
Hey! In fact the problem is not with the List but Rather with your Producer class that has a File type. By inheriting Producer the typing of class File(SQLModel): # table=False by default
name: str
url: str
# That would be the base for your producer object
class ProducerBase(SQLModel): ...
# the files declaration here does not conflict with the declaration in SQL model
class Producer(ProducerBase):
files: Optional[List[File]]
class FileSQL(File, table=True): # `File` itself inherits from SQLModel
__tablename__ = "file"
id: Optional[int] = Field(default=None, primary_key=True)
producer_id: Optional[int] = Field(default=None, foreign_key="producer.id")
producer: Optional["ProducerSQL"] = Relationship(back_populates="files")
class ProducerSQL(ProducerBase, table=True): # `Producer` itself inherits from SQLModel
__tablename__ = "producer"
id: Optional[int] = Field(default=None, primary_key=True)
url: str = Field(unique=True)
files: Optional[List['FileSQL']] = Relationship(back_populates="producer") |
Beta Was this translation helpful? Give feedback.
Ah! That problem is linked to an error in your model definitions.
More specifically, it's because in your
Producer
class you try to set a type asList[File]
. ButList
has no type insqlalchemy
.In SQL databases, when you want to use lists, you typically have to use a
foreign_key
, or sometimes alink_table
.What I usually like to do is define
Create
,Read
andUpdate
models for my data. That way, it's easy later if you want to getRead
data with relationship attributes for example.I would think the best way to get what you want in your case is the following: