[BUG] Variables with annotation of 'typing.Literal' causes a panic #1921
Replies: 10 comments
-
|
I also encountered this issue and ended up implementing the check for a Literal at the beginning of field_type = field.type_
if is_literal_type(field_type):
# Try to get the single type of the literal, error otherwise
types = list({type(x) for x in get_args(field_type)})
if len(types) != 1:
raise RuntimeError("Cannot map a literal with multiple types to a sql type.")
field_type = types[0]To make this work you would still need to import The problem with this solution is that it is specifically for a Literal. So, not sure if this will be immediately accepted to be implemented. Happy to make this into a PR if needed. I eventually stopped using Literal, and chose for an Enum, which works out of the box :) In your case: from enum import Enum
class NameEnum(str, Enum):
FASTAPI = "fastapi"
SQLMODEL = "sqlmodel"
class Cool(SQLModel, table=True):
name: NameEnum |
Beta Was this translation helpful? Give feedback.
-
|
@shifqu this solved my problem, thanks! |
Beta Was this translation helpful? Give feedback.
-
|
I have the same issue and went with the enum solution. But the |
Beta Was this translation helpful? Give feedback.
-
|
I encountered an issue with the enum approach (see #406) where the validation for the field with the enum values silently passes for invalid values. |
Beta Was this translation helpful? Give feedback.
-
|
I have this issue when trying to use a Discriminated Union on a SQLModel a la Pydantic |
Beta Was this translation helpful? Give feedback.
-
|
EDIT: See pydantic/pydantic#5821 (comment) for the main issue and a list of workarounds. I'm deleting the rest of my comment: all its information is present in the linked thread. |
Beta Was this translation helpful? Give feedback.
-
I have to emphasis this code actually write |
Beta Was this translation helpful? Give feedback.
-
Yes, inserting values like In my opinion this is not the behavior anyone should expect since in general database enums can have spaces in them and therefore users should expect SQLModel to use the |
Beta Was this translation helpful? Give feedback.
-
|
Hello, from sqlmodel import SQLModel, Field, String
from typing import Literal
class Cool(SQLModel, table=True):
name: Literal["fastapi", "sqlmodel"] = Field(sa_type=String) |
Beta Was this translation helpful? Give feedback.
-
|
I attempted to implement this and I have a question: would you expect any kind of validation for columns declared as |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
First Check
Commit to Help
Example Code
Description
sqlmodel.main.SQLModelwithtable=Truetyping.Literal[...]TypeErrorexception atsqlmodel/main:get_sqlachemy_typeThis happens because
typing.Literal[...]is a function and since SQLModel usesissubclassto get the variable's SQLAlchemy type;issubclassjust throws aTypeErrorsince it expects a class.Operating System
Linux
Operating System Details
No response
SQLModel Version
0.0.4
Python Version
Python 3.9.6
Additional Context
Funny enough Pydantic had quite the same issue pydantic/pydantic#1026 so it can be as easy as importing
pydantic.typing.is_literal_typeand running an if statement at the top ofget_sqlachemy_typeI think the real issue is that
typing.Literalis an 'Union' type it receive one or more values but since it's often used for one type (e.g. Literal["r", "w", ...]) we can return the type of all the passed values if they are all the same else None. The values can be retrieved withtyping.get_argsas a tuple.Beta Was this translation helpful? Give feedback.
All reactions