Skip to content

LookupError when using EnumType as primary key in SQLAlchemy 1.3 #5

@pbzweihander

Description

@pbzweihander

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions