Skip to content

Commit 3f61b4b

Browse files
committed
drop support for the deprecated database settings
1 parent 27a3a88 commit 3f61b4b

File tree

2 files changed

+57
-91
lines changed

2 files changed

+57
-91
lines changed

README.md

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,21 @@ The following settings control the behavior of the backend:
6060

6161
`OPTIONS` Dictionary. Current available keys are:
6262

63+
``driver``
64+
String. ODBC Driver to use. Default is ``"SQL Server"`` on Windows and
65+
``"FreeTDS"`` on other platforms.
66+
67+
``dsn``
68+
String. A named DSN can be used instead of ``HOST``.
69+
6370
``autocommit``
6471
Boolean. Indicates if pyodbc should direct the the ODBC driver to
6572
activate the autocommit feature. Default value is ``False``.
6673

6774
``MARS_Connection``
6875
Boolean. Only relevant when running on Windows and with SQL Server 2005
6976
or later through MS *SQL Server Native client* driver (i.e. setting
70-
``DATABASE_ODBC_DRIVER`` to ``"SQL Native Client"``). See
77+
``driver`` to ``"SQL Server Native Client 11.0"``). See
7178
http://msdn.microsoft.com/en-us/library/ms131686.aspx.
7279
Default value is ``False``.
7380

@@ -87,23 +94,15 @@ The following settings control the behavior of the backend:
8794

8895
See http://freetds.org/userguide/dsnless.htm for more information.
8996

90-
### ``django-pyodbc``-specific settings
91-
92-
``ODBC_DSN``
93-
String. A named DSN can be used instead of ``DATABASE_HOST``.
94-
95-
``ODBC_DRIVER``
96-
String. ODBC Driver to use. Default is ``"SQL Server"`` on Windows and
97-
``"FreeTDS"`` on other platforms.
98-
99-
``EXTRA_PARAMS``
100-
String. Additional parameters for the ODBC connection. The format is
101-
``"param=value;param=value"``.
97+
``extra_params``
98+
String. Additional parameters for the ODBC connection. The format is
99+
``"param=value;param=value"``.
102100

103-
``COLLATION``
104-
String. Name of the collation to use when performing text field lookups
105-
against the database. Default value is ``"Latin1_General_CI_AS"``.
106-
For Chinese language you can set it to ``"Chinese_PRC_CI_AS"``.
101+
``collation``
102+
String. Name of the collation to use when performing text field lookups
103+
against the database. For Chinese language you can set it to
104+
``"Chinese_PRC_CI_AS"``. The default collation for the database
105+
will be used if no value is specified.
107106

108107
License
109108
-------

django_pyodbc/base.py

Lines changed: 41 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,21 @@
11
"""
22
MS SQL Server database backend for Django.
33
"""
4-
5-
import logging
64
import os
75
import re
8-
import warnings
6+
7+
from django.core.exceptions import ImproperlyConfigured
98

109
try:
1110
import pyodbc as Database
1211
except ImportError, e:
13-
from django.core.exceptions import ImproperlyConfigured
1412
raise ImproperlyConfigured("Error loading pyodbc module: %s" % e)
1513

1614
m = re.match(r'(\d+)\.(\d+)\.(\d+)(?:-beta(\d+))?', Database.version)
1715
vlist = list(m.groups())
1816
if vlist[3] is None: vlist[3] = '9999'
1917
pyodbc_ver = tuple(map(int, vlist))
2018
if pyodbc_ver < (2, 0, 38, 9999):
21-
from django.core.exceptions import ImproperlyConfigured
2219
raise ImproperlyConfigured("pyodbc 2.0.38 or newer is required; you have %s" % Database.version)
2320

2421
from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseValidation
@@ -41,35 +38,6 @@
4138
from django_pyodbc.creation import DatabaseCreation
4239
from django_pyodbc.introspection import DatabaseIntrospection
4340

44-
warnings.filterwarnings('error', 'The DATABASE_ODBC.+ is deprecated', DeprecationWarning, __name__, 0)
45-
46-
logger = logging.getLogger(__name__)
47-
48-
collation = 'Latin1_General_CI_AS'
49-
try:
50-
if hasattr(settings, 'DATABASE_COLLATION'):
51-
warnings.warn(
52-
"The DATABASE_COLLATION setting is going to be deprecated, use DATABASE_OPTIONS['collation'] instead.",
53-
DeprecationWarning
54-
)
55-
collation = settings.DATABASE_COLLATION
56-
elif 'collation' in settings.DATABASE_OPTIONS:
57-
collation = settings.DATABASE_OPTIONS['collation']
58-
except AttributeError:
59-
pass
60-
61-
deprecated = (
62-
('DATABASE_ODBC_DRIVER', 'driver'),
63-
('DATABASE_ODBC_DSN', 'dsn'),
64-
('DATABASE_ODBC_EXTRA_PARAMS', 'extra_params'),
65-
)
66-
for old, new in deprecated:
67-
if hasattr(settings, old):
68-
warnings.warn(
69-
"The %s setting is deprecated, use DATABASE_OPTIONS['%s'] instead." % (old, new),
70-
DeprecationWarning
71-
)
72-
7341
DatabaseError = Database.DatabaseError
7442
IntegrityError = Database.IntegrityError
7543

@@ -101,33 +69,46 @@ class DatabaseWrapper(BaseDatabaseWrapper):
10169
# database collation.
10270
'exact': '= %s',
10371
'iexact': "= UPPER(%s)",
104-
'contains': "LIKE %s ESCAPE '\\' COLLATE " + collation,
105-
'icontains': "LIKE UPPER(%s) ESCAPE '\\' COLLATE "+ collation,
72+
'contains': "LIKE %s ESCAPE '\\'",
73+
'icontains': "LIKE UPPER(%s) ESCAPE '\\'",
10674
'gt': '> %s',
10775
'gte': '>= %s',
10876
'lt': '< %s',
10977
'lte': '<= %s',
110-
'startswith': "LIKE %s ESCAPE '\\' COLLATE " + collation,
111-
'endswith': "LIKE %s ESCAPE '\\' COLLATE " + collation,
112-
'istartswith': "LIKE UPPER(%s) ESCAPE '\\' COLLATE " + collation,
113-
'iendswith': "LIKE UPPER(%s) ESCAPE '\\' COLLATE " + collation,
78+
'startswith': "LIKE %s ESCAPE '\\'",
79+
'endswith': "LIKE %s ESCAPE '\\'",
80+
'istartswith': "LIKE UPPER(%s) ESCAPE '\\'",
81+
'iendswith': "LIKE UPPER(%s) ESCAPE '\\'",
11482

11583
# TODO: remove, keep native T-SQL LIKE wildcards support
11684
# or use a "compatibility layer" and replace '*' with '%'
11785
# and '.' with '_'
118-
'regex': 'LIKE %s COLLATE ' + collation,
119-
'iregex': 'LIKE %s COLLATE ' + collation,
86+
'regex': 'LIKE %s',
87+
'iregex': 'LIKE %s',
12088

12189
# TODO: freetext, full-text contains...
12290
}
12391

12492
def __init__(self, *args, **kwargs):
12593
super(DatabaseWrapper, self).__init__(*args, **kwargs)
12694

127-
if 'OPTIONS' in self.settings_dict:
128-
self.MARS_Connection = self.settings_dict['OPTIONS'].get('MARS_Connection', False)
129-
self.datefirst = self.settings_dict['OPTIONS'].get('datefirst', 7)
130-
self.unicode_results = self.settings_dict['OPTIONS'].get('unicode_results', False)
95+
options = self.settings_dict.get('OPTIONS', None)
96+
97+
if options:
98+
self.MARS_Connection = options.get('MARS_Connection', False)
99+
self.datefirst = options.get('datefirst', 7)
100+
self.unicode_results = options.get('unicode_results', False)
101+
102+
# make lookup operators to be collation-sensitive if needed
103+
self.collation = options.get('collation', None)
104+
if self.collation:
105+
self.operators = dict(self.__class__.operators)
106+
ops = {}
107+
for op in self.operators:
108+
sql = self.operators[op]
109+
if sql.startswith('LIKE '):
110+
ops[op] = '%s COLLATE %s' % (sql, self.collation)
111+
self.operators.update(ops)
131112

132113
if _DJANGO_VERSION >= 13:
133114
self.features = DatabaseFeatures(self)
@@ -145,38 +126,24 @@ def _cursor(self):
145126
new_conn = False
146127
settings_dict = self.settings_dict
147128
db_str, user_str, passwd_str, port_str = None, None, "", None
148-
if _DJANGO_VERSION >= 12:
149-
options = settings_dict['OPTIONS']
150-
if settings_dict['NAME']:
151-
db_str = settings_dict['NAME']
152-
if settings_dict['HOST']:
153-
host_str = settings_dict['HOST']
154-
else:
155-
host_str = 'localhost'
156-
if settings_dict['USER']:
157-
user_str = settings_dict['USER']
158-
if settings_dict['PASSWORD']:
159-
passwd_str = settings_dict['PASSWORD']
160-
if settings_dict['PORT']:
161-
port_str = settings_dict['PORT']
129+
130+
options = settings_dict['OPTIONS']
131+
if settings_dict['NAME']:
132+
db_str = settings_dict['NAME']
133+
if settings_dict['HOST']:
134+
host_str = settings_dict['HOST']
162135
else:
163-
options = settings_dict['DATABASE_OPTIONS']
164-
if settings_dict['DATABASE_NAME']:
165-
db_str = settings_dict['DATABASE_NAME']
166-
if settings_dict['DATABASE_HOST']:
167-
host_str = settings_dict['DATABASE_HOST']
168-
else:
169-
host_str = 'localhost'
170-
if settings_dict['DATABASE_USER']:
171-
user_str = settings_dict['DATABASE_USER']
172-
if settings_dict['DATABASE_PASSWORD']:
173-
passwd_str = settings_dict['DATABASE_PASSWORD']
174-
if settings_dict['DATABASE_PORT']:
175-
port_str = settings_dict['DATABASE_PORT']
136+
host_str = 'localhost'
137+
if settings_dict['USER']:
138+
user_str = settings_dict['USER']
139+
if settings_dict['PASSWORD']:
140+
passwd_str = settings_dict['PASSWORD']
141+
if settings_dict['PORT']:
142+
port_str = settings_dict['PORT']
143+
176144
if self.connection is None:
177145
new_conn = True
178146
if not db_str:
179-
from django.core.exceptions import ImproperlyConfigured
180147
raise ImproperlyConfigured('You need to specify NAME in your Django settings file.')
181148

182149
cstr_parts = []

0 commit comments

Comments
 (0)