django / asgiref

ASGI specification and utilities
https://asgi.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
1.47k stars 209 forks source link

DatabaseError with new version of asgiref #461

Closed abbas-mohd56 closed 5 months ago

abbas-mohd56 commented 5 months ago

Hi,

I have a django project deployed in production with Gunicorn as my server. The project is containerized using docker. I don't have asgiref specified in my requirements so the latest version is installed when I rebuild the image. When I run my webserver using gunicorn, I'm getting the following error:

DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias 'default' was created in thread id 140012881865600 and this is thread id 140012092208800.

I'm only facing this issue when I run the server using Gunicorn, Running server with django's runserver command didn't seem to raise this error. Upon further investigation, I found out that this issue started appearing from asgiref version 3.8.0 .

Traceback:

Environment:

Request Method: GET
Request URL: http://localhost/

Django Version: 3.2.25
Python Version: 3.10.13
Installed Applications:
''
Installed Middleware:
''

Traceback:

File "/usr/local/lib/python3.10/site-packages/django/core/handlers/exception.py" in inner
  47.                 response = get_response(request)

File "/usr/local/lib/python3.10/site-packages/django/core/handlers/base.py" in _get_response
  181.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python3.10/site-packages/django/views/generic/base.py" in view
  64.             self.setup(request, *args, **kwargs)

File "/workspaces/dj_project/app/mixins.py" in setup
  33.         self.obj = P_Model.objects.get(link=request.resolver_match.view_name)

File "/usr/local/lib/python3.10/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/usr/local/lib/python3.10/site-packages/django/db/models/query.py" in get
  431.         num = len(clone)

File "/usr/local/lib/python3.10/site-packages/django/db/models/query.py" in __len__
  262.         self._fetch_all()

File "/usr/local/lib/python3.10/site-packages/django/db/models/query.py" in _fetch_all
  1324.             self._result_cache = list(self._iterable_class(self))

File "/usr/local/lib/python3.10/site-packages/django/db/models/query.py" in __iter__
  51.         results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)

File "/usr/local/lib/python3.10/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1173.             cursor = self.connection.cursor()

File "/usr/local/lib/python3.10/site-packages/django/utils/asyncio.py" in inner
  33.             return func(*args, **kwargs)

File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py" in cursor
  259.         return self._cursor()

File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py" in _cursor
  237.             return self._prepare_cursor(self.create_cursor(name))

File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py" in _prepare_cursor
  227.         self.validate_thread_sharing()

File "/usr/local/lib/python3.10/site-packages/django/db/backends/base/base.py" in validate_thread_sharing
  552.             raise DatabaseError(

Exception Type: DatabaseError at /
Exception Value: DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias 'default' was created in thread id 140012881865600 and this is thread id 140012092208800.

Environment

Python: 3.10.13 Django: 3.2.25 Gunicorn: 22.0.0 gevent: 24.2.1

andrewgodwin commented 5 months ago

This isn't directly an asgiref issue - it looks like you're creating django database objects in one thread and then reusing them in another. Unless you can pinpoint this to exact wrong asgiref behaviour, I suspect you've just ended up in a situation where threading is a little different and has uncovered a bug you already had?