sqlalchemy-enum34
sqlalchemy-enum34 copied to clipboard
LookupError when using EnumType as primary key in SQLAlchemy 1.3
Weird LookupError
raises when using EnumType
as primary key.
I added following test case to test.py
:
class EnumForPkey(enum.Enum):
A = 'a'
B = 'b'
C = 'c'
class TableWithPkeyEnum(Base):
pkey = Column(Enum(EnumForPkey, name='enum_for_pkey'), primary_key=True)
__tablename__ = 'tb_with_pkey_enum'
def test_enum_pkey(fx_session):
row = TableWithPkeyEnum(pkey=EnumForPkey.A)
fx_session.add(row)
fx_session.commit()
row.pkey = EnumForPkey.B
fx_session.commit()
..and ran tox
:
self = Enum('a', 'b', 'c', name='enum_for_pkey'), elem = <EnumForPkey.A: 'a'>
def _db_value_for_elem(self, elem):
try:
> return self._valid_lookup[elem]
E KeyError: <EnumForPkey.A: 'a'>
.tox/py38/lib/python3.8/site-packages/sqlalchemy/sql/sqltypes.py:1499: KeyError
The above exception was the direct cause of the following exception:
fx_session = <sqlalchemy.orm.session.Session object at 0x7fcb79370cd0>
def test_enum_pkey(fx_session):
row = TableWithPkeyEnum(pkey=EnumForPkey.A)
fx_session.add(row)
fx_session.commit()
row.pkey = EnumForPkey.B
> fx_session.commit()
test.py:184:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/py38/lib/python3.8/site-packages/sqlalchemy/orm/session.py:1046: in commit
self.transaction.commit()
...(stack trace)...
.tox/py38/lib/python3.8/site-packages/sqlalchemy/sql/sqltypes.py:1514: in _db_value_for_elem
util.raise_(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def raise_(
exception, with_traceback=None, replace_context=None, from_=False
):
r"""implement "raise" with cause support.
:param exception: exception to raise
:param with_traceback: will call exception.with_traceback()
:param replace_context: an as-yet-unsupported feature. This is
an exception object which we are "replacing", e.g., it's our
"cause" but we don't want it printed. Basically just what
``__suppress_context__`` does but we don't want to suppress
the enclosing context, if any. So for now we make it the
cause.
:param from\_: the cause. this actually sets the cause and doesn't
hope to hide it someday.
"""
if with_traceback is not None:
exception = exception.with_traceback(with_traceback)
if from_ is not False:
exception.__cause__ = from_
elif replace_context is not None:
# no good solution here, we would like to have the exception
# have only the context of replace_context.__context__ so that the
# intermediary exception does not change, but we can't figure
# that out.
exception.__cause__ = replace_context
try:
> raise exception
E LookupError: 'EnumForPkey.A' is not among the defined enum values. Enum name: enum_for_pkey. Possible values: a, b, c
.tox/py38/lib/python3.8/site-packages/sqlalchemy/util/compat.py:182: LookupError
It seems I cannot bind a new value to TableWithPkeyEnum.pkey
with EnumForPkey
.
repr(row.pkey)
returns <EnumForPkey.A: 'a'>
, but I can't assign EnumForPkey.A
to row.pkey
.
Even row.pkey = row.pkey
gives same error.