Repository navigation
Enum types on inherited models don't correctly create type in Postgres #164
Description
Activity
- addedquestionFurther information is requestedFurther information is requested
on Nov 23, 2021 The equiv straight sqlalchemy example code works without issue:
import enum import uuid from sqlalchemy import Enum, Column, create_mock_engine from sqlalchemy.orm import declarative_base, declarative_mixin from sqlalchemy.sql.type_api import TypeEngine from sqlmodel.sql.sqltypes import GUID class MyEnum(enum.Enum): A = 'A' B = 'B' class MyEnum2(enum.Enum): C = 'C' D = 'D' Base = declarative_base() @declarative_mixin class BaseModel: id: uuid.UUID = Column(GUID(), primary_key=True) enum_field: MyEnum2 = Column(Enum(MyEnum2)) class FlatModel(Base): id: uuid.UUID = Column(GUID(), primary_key=True) enum_field: MyEnum = Column(Enum(MyEnum)) __tablename__ = 'flat' class InheritModel(BaseModel, Base): __tablename__ = 'inherit' def dump(sql: TypeEngine, *args, **kwargs): dialect = sql.compile(dialect=engine.dialect) sql_str = str(dialect).rstrip() if sql_str: print(sql_str + ';') engine = create_mock_engine('postgresql://', dump) Base.metadata.create_all(bind=engine, checkfirst=False)
Output
CREATE TYPE myenum AS ENUM ('A', 'B'); CREATE TYPE myenum2 AS ENUM ('C', 'D'); CREATE TABLE flat ( id UUID NOT NULL, enum_field myenum, PRIMARY KEY (id) ); CREATE TABLE inherit ( id UUID NOT NULL, enum_field myenum2, PRIMARY KEY (id) );
- added a commit that references this issue
on Nov 24, 2021 Well the partial-fix seems to be addressed in a number of PRs (#24 , #165 - which i created not knowing #24 was already out there). There is still an issue with inheritance if you manually use
sa_columnin the non-table parent class but I didn't get anywhere understanding why this was the case.Are there more maintainers other than @tiangolo who can look over these PRs and get one of them merged?
Reacted by Toni Alatalo, Jonathan Lifschutz, fraschm1998, Kehan Harman, Daniel Davis, voxofox, chentt, Javier van der Meulen, Tim OSullivan, Ben Rapaport and 1 moreI'm having the same issue but posted it in the closed issue #164:
Thanks everyone for the discussion. ☕
If you want to help me, the best help I can get is helping others with their questions in issues. That's what consumes most of the time.
Maybe this was solved in #165. The fix will be available in the next release, SQLModel
0.0.7, in the next hours. 🎉Could you check and confirm?
- added and removedquestionFurther information is requestedFurther information is requested
on Aug 27, 2022 Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs.
I can confirm that if you do not use
sa_columnfor the field, this is now working as expected withsqlmodel:0.0.8andsqlalchemy:1.4.41.However, a word to other who might end up here - it does NOT work if you manually define the field via
sa_column:class BaseModel(SQLModel): id: uuid.UUID = Field(primary_key=True) # this will not work #enum_field: MyEnum2 = Field(sa_column=Column(Enum(MyEnum2))) # this will work #enum_field: MyEnum2 = Field()
Reacted by Luke MarkhamAn addendum - defining the enum with a string mixin (for nicer on-the-wire strings used with fastapi) using the following notation also breaks the type creation DDL (in that It will not create the dedicated type and the field will just be a varchar):
class MyEnum(str, enum.Enum): A = 'A' B = 'B'
Reacted by Thomas EpelbaumI assume this could easily be fixed by amending the if statement order in main.py:get_sqlalchemy_type function to test the subclass is an Enum before string:
def get_sqlachemy_type(field: ModelField) -> Any: if issubclass(field.type_, str): if field.field_info.max_length: return AutoString(length=field.field_info.max_length) return AutoString ... # move this to the top? if issubclass(field.type_, Enum): return sa_Enum(field.type_) ...
An addendum - defining the enum with a string mixin (for nicer on-the-wire strings used with fastapi) using the following notation also breaks the type creation DDL (in that It will not create the dedicated type and the field will just be a varchar):
class MyEnum(str, enum.Enum): A = 'A' B = 'B'
Any news on this point? I am having this exact issue with enums defined with string mixin (sqlmodel 0.0.6 and 0.0.8 tested without success).
Will we be good to go when #442 is merged? :)
Reacted by Mark SchaalThanks @chriswhite199 and @tepelbaum! This was solved in #669
It will be available in the next release,
0.0.9. 🎉Reacted by Thomas EpelbaumThanks @chriswhite199 and @tepelbaum! This was solved in #669
It will be available in the next release,
0.0.9. 🎉Thanks @tiangolo , and thanks a lot for this!! Can't wait for the pydantic V2 support :)
First Check
Commit to Help
Example Code
Description
When executing the above example code, the output shows that only the enum from FlatModel is correctly created, while the enum from the inherited class is not:
Operating System
macOS
Operating System Details
No response
SQLModel Version
0.0.4
Python Version
3.9.7
Additional Context
No response