Pydantic/SQLAlchemy: 如何使用枚举?
Pydantic/SQLAlchemy: How to work with enums?
如果包含枚举字段,将 sqlalchemy 模型转换为 pydantic 模式(模型)的最佳方法是什么?
SQLalchemy
import enum
from sqlalchemy import Enum, Column, String
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class StateEnum(enum.Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class Adapter(Base):
__tablename__ = 'adapters'
id = Column(String, primary_key=True)
friendly_name = Column(String(256), nullable=False)
state: StateEnum = Column(Enum(StateEnum))
风靡一时
from pydantic import BaseModel
from enum import Enum
class StateEnumDTO(str, Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class AdapterDTO(BaseModel):
friendly_name: str
state: StateEnumDTO # This currently cannot be converted?
class Config:
allow_population_by_field_name = True
orm_mode = True
use_enum_values = True
转化
AdapterDTO.from_orm(Adapter(friendly_name='test', state=StateEnum.CREATED))
这会导致错误
value is not a valid enumeration member; permitted: 'CREATED', 'UPDATED' (type=type_error.enum; enum_values=[<StateEnumDTO.CREATED: 'CREATED'>, <StateEnumDTO.UPDATED: 'UPDATED'>])
我该如何配置
a.) 使用 from_orm 方法序列化?
或
b.) state
字段的创建?
c.) 如何反过来转换?
是否有使用 pydantic 的本机方法或通常如何完成?
更新:
测试用例
def test_enum_conversion_to_dto():
adapter = Adapter(id='1', friendly_name='test', state=StateEnum.CREATED)
adapter_dto = AdapterDTO.from_orm(adapter)
assert adapter_dto.state == StateEnumDTO.CREATED
assert adapter_dto.state.value == StateEnum.CREATED.value
您必须添加 arbitrary_types_allowed = True
到模型配置 class.
from pydantic import BaseModel
from enum import Enum
class StateEnumDTO(str, Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class AdapterDTO(BaseModel):
friendly_name: str
state: StateEnumDTO # This currently cannot be converted?
class Config:
allow_population_by_field_name = True
orm_mode = True
use_enum_values = True
arbitrary_types_allowed = True
Pydantic 要求两个枚举 类 具有相同的类型定义。
在您的例子中,StateEnum
继承自 enum.Enum
,但 StateEnumDTO
继承自 str
和 enum.Enum
。
您可以通过更改 SQLAlchemy 枚举定义来解决此问题:
class StateEnum(str, enum.Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
如果包含枚举字段,将 sqlalchemy 模型转换为 pydantic 模式(模型)的最佳方法是什么?
SQLalchemy
import enum
from sqlalchemy import Enum, Column, String
from sqlalchemy.orm import declarative_base
Base = declarative_base()
class StateEnum(enum.Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class Adapter(Base):
__tablename__ = 'adapters'
id = Column(String, primary_key=True)
friendly_name = Column(String(256), nullable=False)
state: StateEnum = Column(Enum(StateEnum))
风靡一时
from pydantic import BaseModel
from enum import Enum
class StateEnumDTO(str, Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class AdapterDTO(BaseModel):
friendly_name: str
state: StateEnumDTO # This currently cannot be converted?
class Config:
allow_population_by_field_name = True
orm_mode = True
use_enum_values = True
转化
AdapterDTO.from_orm(Adapter(friendly_name='test', state=StateEnum.CREATED))
这会导致错误
value is not a valid enumeration member; permitted: 'CREATED', 'UPDATED' (type=type_error.enum; enum_values=[<StateEnumDTO.CREATED: 'CREATED'>, <StateEnumDTO.UPDATED: 'UPDATED'>])
我该如何配置
a.) 使用 from_orm 方法序列化?
或
b.) state
字段的创建?
c.) 如何反过来转换?
是否有使用 pydantic 的本机方法或通常如何完成?
更新: 测试用例
def test_enum_conversion_to_dto():
adapter = Adapter(id='1', friendly_name='test', state=StateEnum.CREATED)
adapter_dto = AdapterDTO.from_orm(adapter)
assert adapter_dto.state == StateEnumDTO.CREATED
assert adapter_dto.state.value == StateEnum.CREATED.value
您必须添加 arbitrary_types_allowed = True
到模型配置 class.
from pydantic import BaseModel
from enum import Enum
class StateEnumDTO(str, Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'
class AdapterDTO(BaseModel):
friendly_name: str
state: StateEnumDTO # This currently cannot be converted?
class Config:
allow_population_by_field_name = True
orm_mode = True
use_enum_values = True
arbitrary_types_allowed = True
Pydantic 要求两个枚举 类 具有相同的类型定义。
在您的例子中,StateEnum
继承自 enum.Enum
,但 StateEnumDTO
继承自 str
和 enum.Enum
。
您可以通过更改 SQLAlchemy 枚举定义来解决此问题:
class StateEnum(str, enum.Enum):
CREATED = 'CREATED'
UPDATED = 'UPDATED'