Skip to content

bug: get_object_identifier returns Enum instance instead of string value for Enum primary keys #955

@marius-mather

Description

@marius-mather

Checklist

  • The bug is reproducible against the latest release or master.
  • There are no similar issues or pull requests to fix it yet.

Describe the bug

Summary

When using SQLAdmin with SQLModel/SQLAlchemy models that have Enum primary keys, the get_object_identifier() helper function returns the Enum instance instead of its string value. This causes issues with URL generation, e.g. I am seeing non-working URLs like http://localhost:8000/admin/animal/edit/AnimalEnum.DOG

Expected Behavior

get_object_identifier() should return the string value of an enum when used as a primary key, suitable for use in URLs and identifiers.

Actual Behavior

get_object_identifier() returns the enum instance itself, which when converted to string gives the enum name (e.g., "AnimalEnum.DOG") rather than the enum value (e.g., "dog").

Minimal Reproduction Case

from enum import Enum
from sqlmodel import Field, SQLModel, create_engine, Session
from sqlmodel import Enum as DbEnum
from sqladmin.helpers import get_object_identifier

# Define the enum
class AnimalEnum(str, Enum):
    DOG = "dog"
    CAT = "cat"

# Define the model with enum primary key
class Animal(SQLModel, table=True):
    id: AnimalEnum = Field(
        primary_key=True, 
        sa_type=DbEnum(AnimalEnum, name="animalenum")
    )
    name: str

# Create a test instance
engine = create_engine("sqlite:///test.db")
SQLModel.metadata.create_all(engine)

with Session(engine) as session:
    dog = Animal(id=AnimalEnum.DOG, name="Rover")
    session.add(dog)
    session.commit()
    session.refresh(dog)
    
    # Demonstrate the issue
    identifier = get_object_identifier(dog)
    print(f"get_object_identifier(dog): {identifier}")
    print(f"str(get_object_identifier(dog)): {str(identifier)}")
    print(f"type(get_object_identifier(dog)): {type(identifier)}")
    print(f"Expected value: {dog.id.value}")

Output:

get_object_identifier(platform): <AnimalEnum.DOG: 'dog'>
str(get_object_identifier(platform)): AnimalEnum.DOG
type(get_object_identifier(platform)): <enum 'AnimalEnum'>
Expected value: dog

Expected Output

get_object_identifier(dog): dog
str(get_object_identifier(dog)): dog
type(get_object_identifier(dog)): <class 'str'>
Expected value: dog

Proposed Fix

The get_object_identifier() function should check if the primary key value is an Enum instance and return its .value attribute:

def get_object_identifier(obj):
    # ... existing code ...
    if isinstance(pk_value, Enum):
        return pk_value.value
    return pk_value

Steps to reproduce the bug

No response

Expected behavior

No response

Actual behavior

No response

Debugging material

No response

Environment

  • MacOS, Python 3.13, sqladmin 0.21.0

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    not-in-planThis feature/fix is not in a plan. Feel free to contribute with your own PR!

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions