#33533: Should it be impossible for a session dict to return more than one value
for a key?
--------------------------------------------+------------------------
               Reporter:  Michael           |          Owner:  nobody
                   Type:  Uncategorized     |         Status:  new
              Component:  contrib.sessions  |        Version:  4.0
               Severity:  Normal            |       Keywords:
           Triage Stage:  Unreviewed        |      Has patch:  0
    Needs documentation:  0                 |    Needs tests:  0
Patch needs improvement:  0                 |  Easy pickings:  0
                  UI/UX:  0                 |
--------------------------------------------+------------------------
 In my project, I store the serial number of the device that logs in it's
 session. However in the code that gets the value from the session:

 {{{
 SESSION_SERIAL_NUMBER = 'terminal_serial_number'

 user._serial_number = request.session.get(SESSION_SERIAL_NUMBER, '')
 }}}

 Very occasionally throws an error. The part that baffles me is:

 > get() returned more than one Session -- it returned more than 20!

 How can a dict return more than one result, surely that is a bug for a
 dict to return more than one value?

 Note: When I query the database `django_sessions` table with the given
 `sessionid`, it only returns one row.

 Heres the error (from the email):

 {{{
 Internal Server Error: /accounts/login/

 ProgrammingError at /accounts/login/
 no results to fetch
 }}}

 And the traceback:

 {{{
 Traceback (most recent call last):
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 180, in
 _get_session
     return self._session_cache

 During handling of the above exception ('SessionStore' object has no
 attribute '_session_cache'), another exception occurred:
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/core/handlers/exception.py", line 47, in inner
     response = get_response(request)
   File "./dist/terminals/middleware.py", line 11, in __call__
     user._serial_number = request.session.get(SESSION_SERIAL_NUMBER, '')
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 65, in get
     return self._session.get(key, default)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 185, in
 _get_session
     self._session_cache = self.load()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/db.py", line 43, in load
     s = self._get_session_from_db()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/db.py", line 32, in
 _get_session_from_db
     return self.model.objects.get(
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/query.py", line 443, in get
     raise self.model.MultipleObjectsReturned(

 During handling of the above exception (get() returned more than one
 Session -- it returned more than 20!), another exception occurred:
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 180, in
 _get_session
     return self._session_cache

 During handling of the above exception ('SessionStore' object has no
 attribute '_session_cache'), another exception occurred:
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/utils.py", line 97, in inner
     return func(*args, **kwargs)

 The above exception (no results to fetch) was the direct cause of the
 following exception:
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/core/handlers/exception.py", line 47, in inner
     response = get_response(request)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/utils/deprecation.py", line 126, in __call__
     response = response or self.get_response(request)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/core/handlers/exception.py", line 49, in inner
     response = response_for_exception(request, exc)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/core/handlers/exception.py", line 110, in
 response_for_exception
     response = handle_uncaught_exception(request,
 get_resolver(get_urlconf()), sys.exc_info())
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/core/handlers/exception.py", line 149, in
 handle_uncaught_exception
     return callback(request)
   File "./core/base/views.py", line 152, in error_500_view
     response = render(request, "core.base/500.html", context=context)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/shortcuts.py", line 19, in render
     content = loader.render_to_string(template_name, context, request,
 using=using)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/template/loader.py", line 62, in render_to_string
     return template.render(context, request)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/template/backends/django.py", line 61, in render
     return self.template.render(context)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/template/base.py", line 174, in render
     with context.bind_template(self):
   File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__
     return next(self.gen)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/debug_toolbar/panels/templates/panel.py", line 46, in
 _request_context_bind_template
     context = processor(self.request)
   File "./core/base/context_processors.py", line 13, in project
     menu = get_plug_menu(request.user)
   File "./dist/plug/menu.py", line 58, in get_plug_menu
     if user.is_anonymous or user.is_terminal:
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/utils/functional.py", line 248, in inner
     self._setup()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/utils/functional.py", line 384, in _setup
     self._wrapped = self._setupfunc()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/auth/middleware.py", line 25, in <lambda>
     request.user = SimpleLazyObject(lambda: get_user(request))
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/auth/middleware.py", line 11, in get_user
     request._cached_user = auth.get_user(request)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/auth/__init__.py", line 177, in get_user
     user_id = _get_user_session_key(request)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/auth/__init__.py", line 60, in
 _get_user_session_key
     return
 get_user_model()._meta.pk.to_python(request.session[SESSION_KEY])
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 50, in
 __getitem__
     return self._session[key]
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/base.py", line 185, in
 _get_session
     self._session_cache = self.load()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/db.py", line 43, in load
     s = self._get_session_from_db()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/contrib/sessions/backends/db.py", line 32, in
 _get_session_from_db
     return self.model.objects.get(
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/manager.py", line 85, in manager_method
     return getattr(self.get_queryset(), name)(*args, **kwargs)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/query.py", line 435, in get
     num = len(clone)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/query.py", line 262, in __len__
     self._fetch_all()
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/query.py", line 1354, in _fetch_all
     self._result_cache = list(self._iterable_class(self))
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/query.py", line 51, in __iter__
     results = compiler.execute_sql(chunked_fetch=self.chunked_fetch,
 chunk_size=self.chunk_size)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/sql/compiler.py", line 1234, in execute_sql
     return list(result)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/sql/compiler.py", line 1678, in cursor_iter
     for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/models/sql/compiler.py", line 1678, in <lambda>
     for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/utils.py", line 97, in inner
     return func(*args, **kwargs)
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/utils.py", line 90, in __exit__
     raise dj_exc_value.with_traceback(traceback) from exc_value
   File "/home/company/.venv/project/lib/python3.8/site-
 packages/django/db/utils.py", line 97, in inner
     return func(*args, **kwargs)

 Exception Type: ProgrammingError at /accounts/login/
 Exception Value: no results to fetch
 Request information:
 USER: AnonymousUser
 }}}

 This is the middleware it sits in:
 {{{
 from dist.terminals.apps import SESSION_SERIAL_NUMBER

 class UserSerialNumberMiddleware:
     def __init__(self, get_response):
         self.get_response = get_response
         # One-time configuration and initialization.

     def __call__(self, request):
         user = request.user
         user._serial_number = request.session.get(SESSION_SERIAL_NUMBER,
 '')
         response = self.get_response(request)
         return response
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33533>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/053.653c8a27535387745cfbcc5ed65a00be%40djangoproject.com.

Reply via email to