microsoft / mssql-django

The Microsoft Django backend for SQL Server provides a connectivity layer for Django on SQL Server or Azure SQL DB.
Other
347 stars 112 forks source link

[QUESTION] is it possible to Override base.py DatabaseWrapper class definition? #317

Closed EstebanHelpDesk closed 11 months ago

EstebanHelpDesk commented 11 months ago

I'm working with a mixed database that includes tables created using Django ORM and some manually crafted procedures. I've noticed that the datetime fields created in the database are of type datetime2. This becomes problematic when dealing with stored procedures that expect datetime.

I want to override this default behavior to create new models with datetime instead of datetime2. Is it possible to achieve this as a patch within my app without modifying the base.py file? some help or example here, please!

class DatabaseWrapper(BaseDatabaseWrapper): vendor = 'microsoft' display_name = 'SQL Server'

# This dictionary maps Field objects to their associated MS SQL column types, represented as strings.
# Column-type strings can contain format strings, which will be interpolated against the values of Field.__dict__
# before being output. If a column type is set to None, it won't be included in the output.

data_types = {
    'AutoField': 'int',
    'BigAutoField': 'bigint',
    'BigIntegerField': 'bigint',
    'BinaryField': 'varbinary(%(max_length)s)',
    'BooleanField': 'bit',
    'CharField': 'nvarchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',  # Changed from 'datetime2'
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'nvarchar(%(max_length)s)',
    'FilePathField': 'nvarchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'int',
    'IPAddressField': 'nvarchar(15)',
    'GenericIPAddressField': 'nvarchar(39)',
    'JSONField': 'nvarchar(max)',
    'NullBooleanField': 'bit',
    'OneToOneField': 'int',
    'PositiveIntegerField': 'int',
    'PositiveSmallIntegerField': 'smallint',
    'PositiveBigIntegerField': 'bigint',
    'SlugField': 'nvarchar(%(max_length)s)',
    'SmallAutoField': 'smallint',
    'SmallIntegerField': 'smallint',
    'TextField': 'nvarchar(max)',
    'TimeField': 'time',
    'UUIDField': 'char(32)',
}

In this modified code, I changed the 'DateTimeField' entry from 'datetime2' to 'datetime' to address the issue with datetime fields. This adjustment should help avoid conflicts with stored procedures that rely on datetime rather than datetime2

EstebanHelpDesk commented 11 months ago

For some newbie as me, I do it using a monkey patch in my settings.py under database specification. In same way I changed nvarchar to varchar to test speed.. but not the point here.

# Cambiar el tipo de datos  datetime2 a datetime como default para coexistir con logica antigua y los sp de la base creada.
from mssql.base import DatabaseWrapper
DatabaseWrapper.data_types['DateTimeField'] = 'datetime'
# Cambiar el tipo de datos  nvarchar a varchar para coexistir con los sp de la base creada manualmente.
DatabaseWrapper.data_types['CharField'] = 'varchar(%(max_length)s)'