Skip to content

Commit 4ed97c6

Browse files
authored
Merge pull request #16 from microsoft/dev
Prepare for 1.0b1 release
2 parents 1fef391 + bcf3527 commit 4ed97c6

File tree

12 files changed

+277
-85
lines changed

12 files changed

+277
-85
lines changed

README.md

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ We hope you enjoy using the MSSQL-Django 3rd party backend.
1616
- Compatible with
1717
[Micosoft ODBC Driver for SQL Server](https://docs.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server),
1818
[SQL Server Native Client](https://msdn.microsoft.com/en-us/library/ms131321(v=sql.120).aspx),
19-
and [FreeTDS](http://www.freetds.org/) ODBC drivers
19+
and [FreeTDS](https://www.freetds.org/) ODBC drivers
2020

2121
## Dependencies
2222

@@ -27,14 +27,14 @@ We hope you enjoy using the MSSQL-Django 3rd party backend.
2727

2828
1. Install pyodbc 3.0 (or newer) and Django 2.2 (or 3.0)
2929

30-
2. Install mssql-django ::
30+
2. Install mssql-django:
3131

32-
pip install mssql-django
32+
pip install mssql-django
3333

34-
3. Set the ``ENGINE`` setting in the `settings.py` file used by
35-
your Django application or project to ``'mssql'``
34+
3. Set the `ENGINE` setting in the `settings.py` file used by
35+
your Django application or project to `'mssql'`:
3636

37-
``'ENGINE': 'mssql'``
37+
'ENGINE': 'mssql'
3838

3939
## Configuration
4040

@@ -45,15 +45,15 @@ in DATABASES control the behavior of the backend:
4545

4646
- ENGINE
4747

48-
String. It must be ``"mssql"``.
48+
String. It must be `"mssql"`.
4949

5050
- NAME
5151

5252
String. Database name. Required.
5353

5454
- HOST
5555

56-
String. SQL Server instance in ``"server\instance"`` format.
56+
String. SQL Server instance in `"server\instance"` format.
5757

5858
- PORT
5959

@@ -62,7 +62,7 @@ in DATABASES control the behavior of the backend:
6262

6363
- USER
6464

65-
String. Database user name in ``"user"`` format.
65+
String. Database user name in `"user"` format.
6666
If not given then MS Integrated Security will be used.
6767

6868
- PASSWORD
@@ -71,22 +71,22 @@ in DATABASES control the behavior of the backend:
7171

7272
- AUTOCOMMIT
7373

74-
Boolean. Set this to False if you want to disable
74+
Boolean. Set this to `False` if you want to disable
7575
Django's transaction management and implement your own.
7676

77-
and the following entries are also available in the TEST dictionary
77+
and the following entries are also available in the `TEST` dictionary
7878
for any given database-level settings dictionary:
7979

8080
- NAME
8181

8282
String. The name of database to use when running the test suite.
83-
If the default value (``None``) is used, the test database will use
84-
the name "test\_" + ``NAME``.
83+
If the default value (`None`) is used, the test database will use
84+
the name `"test\_" + NAME`.
8585

8686
- COLLATION
8787

8888
String. The collation order to use when creating the test database.
89-
If the default value (``None``) is used, the test database is assigned
89+
If the default value (`None`) is used, the test database is assigned
9090
the default collation of the instance of SQL Server.
9191

9292
- DEPENDENCIES
@@ -97,7 +97,7 @@ for any given database-level settings dictionary:
9797
- MIRROR
9898

9999
String. The alias of the database that this database should
100-
mirror during testing. Default value is ``None``.
100+
mirror during testing. Default value is `None`.
101101
See the official Django documentation for more details.
102102

103103
### OPTIONS
@@ -106,22 +106,22 @@ Dictionary. Current available keys are:
106106

107107
- driver
108108

109-
String. ODBC Driver to use (``"ODBC Driver 17 for SQL Server"``,
110-
``"SQL Server Native Client 11.0"``, ``"FreeTDS"`` etc).
111-
Default is ``"ODBC Driver 17 for SQL Server"``.
109+
String. ODBC Driver to use (`"ODBC Driver 17 for SQL Server"`,
110+
`"SQL Server Native Client 11.0"`, `"FreeTDS"` etc).
111+
Default is `"ODBC Driver 17 for SQL Server"`.
112112

113113
- isolation_level
114114

115115
String. Sets [transaction isolation level](https://docs.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql)
116116
for each database session. Valid values for this entry are
117-
``READ UNCOMMITTED``, ``READ COMMITTED``, ``REPEATABLE READ``,
118-
``SNAPSHOT``, and ``SERIALIZABLE``. Default is ``None`` which means
117+
`READ UNCOMMITTED`, `READ COMMITTED`, `REPEATABLE READ`,
118+
`SNAPSHOT`, and `SERIALIZABLE`. Default is `None` which means
119119
no isolation levei is set to a database session and SQL Server default
120120
will be used.
121121

122122
- dsn
123123

124-
String. A named DSN can be used instead of ``HOST``.
124+
String. A named DSN can be used instead of `HOST`.
125125

126126
- host_is_server
127127

@@ -192,7 +192,7 @@ The following project-level settings also control the behavior of the backend:
192192

193193
Here is an example of the database settings:
194194

195-
```
195+
```python
196196
DATABASES = {
197197
'default': {
198198
'ENGINE': 'mssql',
@@ -211,6 +211,7 @@ Here is an example of the database settings:
211211
# set this to False if you want to turn off pyodbc's connection pooling
212212
DATABASE_CONNECTION_POOLING = False
213213
```
214+
214215
## Limitations
215216

216217
The following features are currently not supported:
@@ -238,7 +239,7 @@ contact [[email protected]](mailto:[email protected]) with any additio
238239

239240
## Security Reporting Instructions
240241

241-
For security reporting instructions please refer to the SECURITY.md file in this repository.
242+
For security reporting instructions please refer to the [`SECURITY.md`](SECURITY.md) file in this repository.
242243

243244
## Trademarks
244245

azure-pipelines.yml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ variables:
66
agent.preferPowerShellOnContainers: true
77

88
schedules:
9-
- cron: "0 0 * * *"
9+
- cron: "0 9 * * *"
1010
displayName: Daily midnight build
1111
branches:
1212
include:
@@ -20,12 +20,26 @@ jobs:
2020

2121
strategy:
2222
matrix:
23+
Python 3.8 - Django 3.1:
24+
python.version: '3.8'
25+
tox.env: 'py38-django31'
26+
Python 3.7 - Django 3.1:
27+
python.version: '3.7'
28+
tox.env: 'py37-django31'
29+
Python 3.6 - Django 3.1:
30+
python.version: '3.6'
31+
tox.env: 'py36-django31'
32+
33+
Python 3.8 - Django 3.0:
34+
python.version: '3.8'
35+
tox.env: 'py38-django30'
2336
Python 3.7 - Django 3.0:
2437
python.version: '3.7'
2538
tox.env: 'py37-django30'
2639
Python 3.6 - Django 3.0:
2740
python.version: '3.6'
2841
tox.env: 'py36-django30'
42+
2943
Python 3.7 - Django 2.2:
3044
python.version: '3.7'
3145
tox.env: 'py37-django22'
@@ -62,12 +76,26 @@ jobs:
6276

6377
strategy:
6478
matrix:
79+
Python 3.8 - Django 3.1:
80+
python.version: '3.8'
81+
tox.env: 'py38-django31'
82+
Python 3.7 - Django 3.1:
83+
python.version: '3.7'
84+
tox.env: 'py37-django31'
85+
Python 3.6 - Django 3.1:
86+
python.version: '3.6'
87+
tox.env: 'py36-django31'
88+
89+
Python 3.8 - Django 3.0:
90+
python.version: '3.8'
91+
tox.env: 'py38-django30'
6592
Python 3.7 - Django 3.0:
6693
python.version: '3.7'
6794
tox.env: 'py37-django30'
6895
Python 3.6 - Django 3.0:
6996
python.version: '3.6'
7097
tox.env: 'py36-django30'
98+
7199
Python 3.7 - Django 2.2:
72100
python.version: '3.7'
73101
tox.env: 'py37-django22'
@@ -87,7 +115,7 @@ jobs:
87115
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
88116
curl https://packages.microsoft.com/config/ubuntu/18.04/prod.list | sudo tee /etc/apt/sources.list.d/mssql-release.list
89117
sudo apt-get update
90-
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17 g++ unixodbc-dev
118+
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql17 g++ unixodbc-dev libmemcached-dev
91119
displayName: Install SQL Server
92120
93121
- script: |

mssql/creation.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55
import os
66

77
from django.db.backends.base.creation import BaseDatabaseCreation
8+
from django import VERSION as django_version
89

910

1011
class DatabaseCreation(BaseDatabaseCreation):
1112

13+
def cursor(self):
14+
if django_version >= (3, 1):
15+
return self.connection._nodb_cursor()
16+
17+
return self.connection._nodb_connection.cursor()
18+
1219
def _destroy_test_db(self, test_database_name, verbosity):
1320
"""
1421
Internal implementation - remove the test db tables.
@@ -17,7 +24,7 @@ def _destroy_test_db(self, test_database_name, verbosity):
1724
# ourselves. Connect to the previous database (not the test database)
1825
# to do so, because it's not allowed to delete a database while being
1926
# connected to it.
20-
with self.connection._nodb_connection.cursor() as cursor:
27+
with self.cursor() as cursor:
2128
to_azure_sql_db = self.connection.to_azure_sql_db
2229
if not to_azure_sql_db:
2330
cursor.execute("ALTER DATABASE %s SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
@@ -39,7 +46,7 @@ def enable_clr(self):
3946
This function will not fail if current user doesn't have
4047
permissions to enable clr, and clr is already enabled
4148
"""
42-
with self._nodb_connection.cursor() as cursor:
49+
with self.cursor() as cursor:
4350
# check whether clr is enabled
4451
cursor.execute('''
4552
SELECT value FROM sys.configurations
@@ -89,7 +96,7 @@ def install_regex_clr(self, database_name):
8996

9097
self.enable_clr()
9198

92-
with self._nodb_connection.cursor() as cursor:
99+
with self.self.cursor() as cursor:
93100
for s in sql:
94101
cursor.execute(s)
95102

mssql/features.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
2424
requires_literal_defaults = True
2525
requires_sqlparse_for_splitting = False
2626
supports_boolean_expr_in_select_clause = False
27+
supports_deferrable_unique_constraints = False
2728
supports_ignore_conflicts = False
2829
supports_index_on_text_field = False
30+
supports_json_field = False
2931
supports_paramstyle_pyformat = False
3032
supports_regex_backreferencing = True
3133
supports_sequence_reset = False

mssql/functions.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from django.db.models.functions import Cast
77
from django.db.models.functions.math import ATan2, Log, Ln, Mod, Round
88
from django.db.models.expressions import Case, Exists, OrderBy, When
9-
from django.db.models.lookups import Lookup
9+
from django.db.models.lookups import Lookup, In
1010

1111
DJANGO3 = VERSION[0] >= 3
1212

@@ -91,11 +91,29 @@ def sqlserver_orderby(self, compiler, connection):
9191
return self.as_sql(compiler, connection, template=template)
9292

9393

94+
def split_parameter_list_as_sql(self, compiler, connection):
95+
# Insert In clause parameters 1000 at a time into a temp table.
96+
lhs, _ = self.process_lhs(compiler, connection)
97+
_, rhs_params = self.batch_process_rhs(compiler, connection)
98+
99+
with connection.cursor() as cursor:
100+
cursor.execute("IF OBJECT_ID('tempdb.dbo.#Temp_params', 'U') IS NOT NULL DROP TABLE #Temp_params; ")
101+
cursor.execute("CREATE TABLE #Temp_params (params nvarchar(32))")
102+
for offset in range(0, len(rhs_params), 1000):
103+
sqls_params = rhs_params[offset: offset + 1000]
104+
sqls_params = ", ".join("('{}')".format(item) for item in sqls_params)
105+
cursor.execute("INSERT INTO #Temp_params VALUES %s" % sqls_params)
106+
107+
in_clause = lhs + ' IN ' + '(SELECT params from #Temp_params)'
108+
109+
return in_clause, ()
110+
94111
ATan2.as_microsoft = sqlserver_atan2
95112
Log.as_microsoft = sqlserver_log
96113
Ln.as_microsoft = sqlserver_ln
97114
Mod.as_microsoft = sqlserver_mod
98115
Round.as_microsoft = sqlserver_round
116+
In.split_parameter_list_as_sql = split_parameter_list_as_sql
99117

100118
if DJANGO3:
101119
Lookup.as_microsoft = sqlserver_lookup

0 commit comments

Comments
 (0)