问题

SQLAlchemy的类型可以设为Enum,默认使用key

e.g.
1
2
3
4
class MyEnum(Enum):
one = 1
two = 2
three = 3

设置Column("column_name", Enum(MyEnum))插入的是"one""two"等key字符串

官方提供了参数values_callable,但value必须是字符串

内部使用value的len属性构造object,而数值没有该属性

假设value为字符串’1’,’2’,’3’

e.g.
1
Column("column_name", Enum(MyEnum, values_callable=lambda x: [e.value for e in x]))

解决办法

继承TypeDecorator创建自定义Enum列类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from sqlalchemy import Integer, TypeDecorator
class IntEnum(TypeDecorator):
"""https://stackoverflow.com/questions/33612625/how-to-model-enums-backed-by-integers-with-sqlachemy#answer-41634765"""
impl = Integer

def __init__(self, enum_type, *args, **kwargs):
super().__init__(*args, **kwargs)
self._enum_type = enum_type

def process_bind_param(self, value, dialect):
return value.value

def process_result_value(self, value, dialect):
return self._enum_type(value)
  1. 继承自sqlalchemy.TypeDecorator
  2. 设置impl为需要的类型,此处为Integer
  3. 重写process_bind_param,返回value
  4. 重写process_result_value,返回Enum实例

使用方法

e.g.
1
Column("column_name", IntEnum(MyEnum))