0

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.

lorenzo
  • 627
  • 8
  • 12

1 Answers1

1

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()
eatmeimadanish
  • 3,809
  • 1
  • 14
  • 20
  • thank you, I'll prefer sql server this time for some reasons but I appreciate your solution for future projects – lorenzo Jul 29 '20 at 07:00