fastapi / sqlmodel

SQL databases in Python, designed for simplicity, compatibility, and robustness.
https://sqlmodel.tiangolo.com/
MIT License
14.05k stars 626 forks source link

TypeError: issubclass() arg 1 must be a class when having a field with a complex type #67

Open Matthieu-Tinycoaching opened 3 years ago

Matthieu-Tinycoaching commented 3 years ago

First Check

Commit to Help

Example Code

from datetime import datetime
from typing import Optional, List, Tuple, Dict, Union
from sqlmodel import Field, SQLModel, create_engine

class SemanticSearch(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    id_user: int
    date_time: datetime
    query: str
    clean_query: str
    semantic_search_result: List[Tuple[int, Dict[str, Union[str, int, float]]]]

## sqlite
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"

engine = create_engine(sqlite_url, echo=True)

SQLModel.metadata.create_all(engine)

Description

I would like to create a semantic_search table in the database.db sqlite database with the 6 fields specified.

The last field semantic_search_result with List[Tuple[int, Dict[str, Union[str, int, float]]]] type seems to cause the error.

semantic_search_result looks like this for example:

[
   (0, { "acquisCode": str, "code": str, "level": int, "title": str, "similarity_score": float}),
   (1, { "acquisCode": str, "code": str, "level": int, "title": str, "similarity_score": float}),
   (2, { "acquisCode": str, "code": str, "level": int, "title": str, "similarity_score": float})
]

When running the code I got the following error:

Traceback (most recent call last):
  File "/home/matthieu/Code/Python/fastapi-graphql/test_SQLModel.py", line 6, in <module>
    class SemanticSearch(SQLModel, table=True):
  File "/home/matthieu/anaconda3/envs/sts-transformers-gpu-fresh/lib/python3.8/site-packages/sqlmodel/main.py", line 292, in __new__
    col = get_column_from_field(v)
  File "/home/matthieu/anaconda3/envs/sts-transformers-gpu-fresh/lib/python3.8/site-packages/sqlmodel/main.py", line 415, in get_column_from_field
    sa_type = get_sqlachemy_type(field)
  File "/home/matthieu/anaconda3/envs/sts-transformers-gpu-fresh/lib/python3.8/site-packages/sqlmodel/main.py", line 373, in get_sqlachemy_type
    if issubclass(field.type_, str):
TypeError: issubclass() arg 1 must be a class

I got the same error if I tried to define a subclass of the typing_extensions.TypedDict class:

class SemanticSearchDict(TypedDict):
    acquis_code: str
    code: str
    level: int
    title: str
    similarity_score: float

class SemanticSearch(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    id_user: int
    date_time: datetime
    query: str
    clean_query: str
    semantic_search_result: List[Tuple[int, SemanticSearchDict]]

I couldn't find a solution but #57 seems to have the same problem since having the same error.

Operating System

Linux

Operating System Details

Ubuntu 18.04 LTS

SQLModel Version

0.0.4

Python Version

3.8.8

Additional Context

No response

ademoverflow commented 3 years ago

🆙

Matthieu-Tinycoaching commented 2 years ago

Up!

lobotmcj commented 2 years ago

different cause it seems, but #121 has a similar error.

bjoernh commented 2 years ago

same Problem

txemac commented 2 years ago

same problem here!

data-djinn commented 2 years ago

thank you to the maintainers & contributors of this awesome library!

For anyone who encounters this bug while trying to assign a Literal type, the workaround that I used was defining a separate class of Enum instances:

from enum import Enum

class ValidValues:
    class FirstField(str, Enum):
        FIRST_VAL = 'First val',
        SECOND_VAL = 'Second val'

    class SecondField(str, Enum):
        FIRST_VAL = 'First val',
        SECOND_VAL = 'Second val'
# etc..

class MyTable(SQLModel, table=True):
    first_field: ValidValues.FirstField
    second_field: ValidValues.SecondField
    some_str_field: str
# etc...
memark commented 1 year ago

Any update on this issue?

SPablo2191 commented 4 months ago

same happen using UUID4 for id

ShravanSunder commented 3 months ago

Its because of the get_sqlachemy_type function. literals and perhaps dict isnt recognized

2024-06-13 0602 Brave Browser TypeError issubclass() arg 1 must be a class when having a field with a complex type · Issue #67 · tiangolosqlmodel

you can bypass this using sa_column for literal types

  kind: t.Annotated[t.Literal["resource"])] = Field(
    default="resource", sa_column=Column(String)
  )

i think dicts need to be typed to json