I would like to use a SQL Server database in a Django app that I can scale in the future.
The app would be I/O bound, so I thought the best way to make it scalable is to use Gunicorn with the gevent worker class.
The problem is that for using Gunicorn with --worker-class gevent
the Django app should be gevent compliant and usually happens that some database clients aren't compatible (eg: mysqlclient lib).
I found this SQL Server backend for Django: https://pypi.org/project/django-mssql-backend/ but I'm not able to understand if it is gevent compliant (aka "green").
I know that it would be so if it only uses standard socket/networking python libs that can be easily monkey-patched but I can't understand if this is the case. Is pyodbc SQL Server backend gevent compliant?
On the official manual and on Google I can't find further information.
If you are willing to switch to Postgresql, I have a module already setup to do everything you need:
Python Postgres psycopg2 ThreadedConnectionPool exhausted
This includes a connection pool to handle thousands of simultaneous connections.
** Update **
I have a solution using Pymssql:
import gevent.socket
import pymssql
import traceback
import sys
def wait_callback(read_fileno):
gevent.socket.wait_read(read_fileno)
pymssql.set_wait_callback(wait_callback)
def conn():
return pymssql.connect(server=server, user=user, password=password, autocommit=True)
def fetchone(SQL, *args):
with conn() as c:
with c.cursor() as cursor:
try:
cursor.execute(SQL, args)
except TypeError:
cursor.execute(SQL, args[0])
except Exception as exc:
print(sys._getframe().f_back.f_code)
print(sys._getframe().f_back.f_code.co_name)
traceback.print_exc()
return ()
return cursor.fetchone()
def fetchall(SQL, *args):
with conn() as c:
with c.cursor() as cursor:
try:
cursor.execute(SQL, args)
except TypeError:
cursor.execute(SQL, args[0])
except Exception as exc:
print(sys._getframe().f_back.f_code)
print(sys._getframe().f_back.f_code.co_name)
traceback.print_exc()
return ()
return cursor.fetchall()
def execute(PSQL, *args):
with conn() as c:
with c.cursor() as cursor:
try:
cursor.execute(PSQL, args)
except TypeError:
cursor.execute(PSQL, args[0])
except ValueError:
cursor.execute(PSQL, tuple(args[0]))
except:
print(sys._getframe().f_back.f_code)
print(sys._getframe().f_back.f_code.co_name)
traceback.print_exc()
return ()
finally:
return cursor.close()