具有整数值的 SQLAlchemy 枚举类型字段
SQLAlchemy Enum type field with integer value
有一个事件模型,我想在其中添加一个 memebers_count 字段来指示参与者的数量。用户将从 select 形式生成单个 selection。我为此使用 Enum 类型。模型看起来像这样
class MembersQuantity(enum.Enum):
two = 2
three = 3
four = 4
five = 5
six = 6
...
nineteen = 19
twenty = 20
thirty = 30
forty = 40
fifty = 50
unlimited = 1000
events = Table(
"events",
metadata,
Column("id", Integer(), primary_key=True),
...
Column("members_count", Enum(MembersQuantity, values_callable=lambda obj: [e.value for e in obj]),
nullable=False,
default=MembersQuantity.two.value,
server_default=MembersQuantity.two.value),
....
输入时控制台出现错误
File "/home/jekson/Projects/own/wplay/./models/events.py", line 64, in <module>
Column("members_count", Enum(MembersQuantity, values_callable=lambda obj: [e.value for e in obj]),
File "<string>", line 2, in __init__
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 139, in warned
return fn(*args, **kwargs)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1383, in __init__
self._enum_init(enums, kw)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1425, in _enum_init
length = max(len(x) for x in self.enums)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1425, in <genexpr>
length = max(len(x) for x in self.enums)
TypeError: object of type 'int' has no len()
我认为问题是 [e.value for e in obj]
应该是 str 而不是 int 并将其替换为 [str(e.value) for e in obj]
但得到另一个错误
sqlalchemy.exc.ArgumentError: Argument 'arg' is expected to be of the type '<class 'str'>' or '<class 'sqlalchemy.sql.elements.ClauseElement'>' or '<class 'sqlalchemy.sql.elements.TextClause'>', got '<class 'int'>'
怎么了?
问题是你想坚持什么? two
或 2 或 <MembersQuantity.two: 2>
?
SQLAlchemy docs 状态:
Above, the string names of each element, e.g. “one”, “two”, “three”, are persisted to the database;
the values of the Python Enum, here indicated as integers, are not used;
the value of each enum can therefore be any kind of Python object whether or not it is persistable.
所以如果你有枚举的整数值,你可能应该有这样的东西:
Column(
"members_count",
Enum(MembersQuantity),
nullable=False,
default=MembersQuantity.two.name,
server_default=MembersQuantity.two.name
)
name
属性是 two
,而 value
属性在你的例子中是 2。但是你只坚持 left-hand 侧弦。
仅当您想要保留值而不是名称时才应使用 values_callable
,但文档还指出:value_callables - a callable which will be passed the PEP-435 compliant enumerated type, which should then return a list of string values to be persisted
。所以只有当它是一个字符串时你才能持久化值。
这里有一个可能有用的主题:
有一个事件模型,我想在其中添加一个 memebers_count 字段来指示参与者的数量。用户将从 select 形式生成单个 selection。我为此使用 Enum 类型。模型看起来像这样
class MembersQuantity(enum.Enum):
two = 2
three = 3
four = 4
five = 5
six = 6
...
nineteen = 19
twenty = 20
thirty = 30
forty = 40
fifty = 50
unlimited = 1000
events = Table(
"events",
metadata,
Column("id", Integer(), primary_key=True),
...
Column("members_count", Enum(MembersQuantity, values_callable=lambda obj: [e.value for e in obj]),
nullable=False,
default=MembersQuantity.two.value,
server_default=MembersQuantity.two.value),
....
输入时控制台出现错误
File "/home/jekson/Projects/own/wplay/./models/events.py", line 64, in <module>
Column("members_count", Enum(MembersQuantity, values_callable=lambda obj: [e.value for e in obj]),
File "<string>", line 2, in __init__
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 139, in warned
return fn(*args, **kwargs)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1383, in __init__
self._enum_init(enums, kw)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1425, in _enum_init
length = max(len(x) for x in self.enums)
File "/home/jekson/virtualenvs/wplay/lib/python3.9/site-packages/sqlalchemy/sql/sqltypes.py", line 1425, in <genexpr>
length = max(len(x) for x in self.enums)
TypeError: object of type 'int' has no len()
我认为问题是 [e.value for e in obj]
应该是 str 而不是 int 并将其替换为 [str(e.value) for e in obj]
但得到另一个错误
sqlalchemy.exc.ArgumentError: Argument 'arg' is expected to be of the type '<class 'str'>' or '<class 'sqlalchemy.sql.elements.ClauseElement'>' or '<class 'sqlalchemy.sql.elements.TextClause'>', got '<class 'int'>'
怎么了?
问题是你想坚持什么? two
或 2 或 <MembersQuantity.two: 2>
?
SQLAlchemy docs 状态:
Above, the string names of each element, e.g. “one”, “two”, “three”, are persisted to the database;
the values of the Python Enum, here indicated as integers, are not used;
the value of each enum can therefore be any kind of Python object whether or not it is persistable.
所以如果你有枚举的整数值,你可能应该有这样的东西:
Column(
"members_count",
Enum(MembersQuantity),
nullable=False,
default=MembersQuantity.two.name,
server_default=MembersQuantity.two.name
)
name
属性是 two
,而 value
属性在你的例子中是 2。但是你只坚持 left-hand 侧弦。
仅当您想要保留值而不是名称时才应使用 values_callable
,但文档还指出:value_callables - a callable which will be passed the PEP-435 compliant enumerated type, which should then return a list of string values to be persisted
。所以只有当它是一个字符串时你才能持久化值。
这里有一个可能有用的主题: