Skip to content

Object identifier values function not parsing correctly path parameters when a field is DateTime #858

@co-incc

Description

@co-incc

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

Opening a record with a DateTime type column in the composite primary key will result in a 500 error.

The object_identifier_values() function in helper.py fails to convert to Python's datetime.datetime type, resulting in an error.

Steps to reproduce the bug

  1. Create a model which contains a PK with a DateTime value and other PK.
  2. Create an admin view for that model.
  3. Try to access the admin view and the detail/edit view or deleting the record. You will get a 500 error.

The test code to reproduce is below.

class PersonWithDateTime(Base):
    __tablename__ = "users_with_datetime"

    family_id = Column(String, ForeignKey("family.id"), primary_key=True)
    member_id = Column(Integer, primary_key=True)
    version = Column(String, primary_key=True)
    date = Column(DateTime, primary_key=True)


def test_multi_pk_id_values_with_datetime_column():
    def id_values(ident):
        return object_identifier_values(ident, PersonWithDateTime)

    assert id_values("Johnson;7;A;2024-01-01 10:00:00") == ("Johnson", 7, "A", datetime.datetime(2024, 1, 1, 10, 0, 0))

Expected behavior

Records containing DateTime type as a composite primary key can be viewed and edited.

Actual behavior

Server error.

Debugging material

Traceback

Traceback (most recent call last):
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 401, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __call__
    raise exc
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 460, in handle
    await self.app(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 187, in __call__
    raise exc
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/sessions.py", line 85, in __call__
    await self.app(scope, receive, send_wrapper)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/starlette/routing.py", line 73, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/sqladmin/authentication.py", line 68, in wrapper_decorator
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/sqladmin/application.py", line 467, in details
    model = await model_view.get_object_for_details(request.path_params["pk"])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/sqladmin/models.py", line 844, in get_object_for_details
    stmt = self._stmt_by_identifier(value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/sqladmin/models.py", line 862, in _stmt_by_identifier
    values = object_identifier_values(identifier, self.model)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jsaito/git/myproject/.venv/lib/python3.12/site-packages/sqladmin/helpers.py", line 231, in object_identifier_values
    value = False if part == "False" else type_(part)
                                          ^^^^^^^^^^^
TypeError: 'str' object cannot be interpreted as an integer

Environment

  • Python 3.12, MacOS, sqladmin==0.20.1

Additional context

PR #859

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions