miguelgrinberg / python-socketio

Python Socket.IO server and client
MIT License
3.98k stars 586 forks source link

DatabaseError: DatabaseWrapper objects created in a thread can only be used in that same thread. #631

Closed praveenydv closed 3 years ago

praveenydv commented 3 years ago

my wsgi.py:

import os
from django.core.wsgi import get_wsgi_application
import socketio
import django 
django.setup()
from myapp.websocketserver import sio
import eventlet
os.environ.setdefault("DJANGO_SETTINGS_MODULE","mysite.settings")
django_app = get_wsgi_application()
application = socketio.WSGIApp(sio, django_app)

my websocketserver.py

import os
import json
from .models import Message,Chat,User
from .views import get_last_10_messages, get_user, get_current_chat,get_file,getchatUsers
import socketio
from django.conf import settings

sio = socketio.Server(json=json,cors_allowed_origins=settings.CORS_URL,async_mode='eventlet')
thread = None

def start():
    print('server started')
    global thread
    if thread is None:
        thread = sio.start_background_task(background_thread)

def background_thread():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        sio.sleep(10)
        count += 1
        sio.emit('serverEvent', {'data': 'Server generated event'},
                 namespace='/test')

@sio.event
def disconnect_request(sid):
    sio.disconnect(sid)

@sio.event
def connect(sid, environ):
    sio.emit('connected_response', {'data': 'Connected', 'count': 0}, room=sid)

@sio.event
def disconnect(sid):
    print('Client disconnected')

@sio.event
def send_mssg(sid, data):
    user_contact = get_user(data['sender'])

    message = Message.objects.create(
        sender=user_contact,
        content=data['message'],
        )
    message.save()
    content = message_to_json(message,data['room'])

    sio.emit('newmessage',content,room=data['room'])

when I run command :

gunicorn --env DJANGO_SETTINGS_MODULE=mysite.settings  -k eventlet -w 1 mysite.wsgi:application 

then I am getting error on send_mssg event:

  File "/home/praveen/.virtualenvs/chatapp-Z9P-4e14/lib/python3.8/site-packages/django/db/backends/base/base.py", line 552, in validate_thread_sharing
    raise DatabaseError(
django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread can only be used in that same thread. The object with alias 'default' was created in thread id 140294944852096 and this is thread id 140294898046752.

I have checked that when I call send_mssg event then It gives error when new message instance is creating...

How to solve this?? Plz help!!!

miguelgrinberg commented 3 years ago

I don't use Django a lot, but based on the error message this means that you are passing a model object obtained in one thread to another thread, which is actually not a valid use case. What you need to do is pass the object id to the other thread, so that it can load the object from the database directly in that same thread.

This error is unrelated to this package, by the way. It's just that this package uses threads so you have to be careful about the threading requirements in Django ORM.