Skip to content

Commit 05f3fe1

Browse files
authored
Fix startup errors in Django 3.1 (#64)
1 parent b81a024 commit 05f3fe1

File tree

7 files changed

+52
-3
lines changed

7 files changed

+52
-3
lines changed

.github/workflows/main.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,14 @@ jobs:
4141
tox_env:
4242
- "py36-django22"
4343
- "py36-django30"
44+
- "py36-django31"
4445

4546
- "py37-django22"
4647
- "py37-django30"
48+
- "py37-django31"
4749

4850
- "py38-django30"
51+
- "py38-django31"
4952

5053
include:
5154
- python: "3.6"
@@ -54,15 +57,24 @@ jobs:
5457
- python: "3.6"
5558
tox_env: "py36-django30"
5659

60+
- python: "3.6"
61+
tox_env: "py36-django31"
62+
5763
- python: "3.7"
5864
tox_env: "py37-django22"
5965

6066
- python: "3.7"
6167
tox_env: "py37-django30"
6268

69+
- python: "3.7"
70+
tox_env: "py37-django31"
71+
6372
- python: "3.8"
6473
tox_env: "py38-django30"
6574

75+
- python: "3.8"
76+
tox_env: "py38-django31"
77+
6678

6779
steps:
6880
- uses: actions/checkout@v2

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,25 @@ matrix:
4141

4242
- { before_install: *linux_before_install, python: "3.6", os: linux, env: TOX_ENV=py36-django22 }
4343
- { before_install: *linux_before_install, python: "3.6", os: linux, env: TOX_ENV=py36-django30 }
44+
- { before_install: *linux_before_install, python: "3.6", os: linux, env: TOX_ENV=py36-django31 }
4445

4546
- { before_install: *linux_before_install, python: "3.7", os: linux, env: TOX_ENV=py37-django22 }
4647
- { before_install: *linux_before_install, python: "3.7", os: linux, env: TOX_ENV=py37-django30 }
48+
- { before_install: *linux_before_install, python: "3.7", os: linux, env: TOX_ENV=py37-django31 }
4749

4850
- { before_install: *linux_before_install, python: "3.8", os: linux, env: TOX_ENV=py38-django30 }
51+
- { before_install: *linux_before_install, python: "3.8", os: linux, env: TOX_ENV=py38-django31 }
4952

5053
- { before_install: *win_before_install, language: sh, python: "3.6", os: windows, env: TOX_ENV=py36-django22 }
5154
- { before_install: *win_before_install, language: sh, python: "3.6", os: windows, env: TOX_ENV=py36-django30 }
55+
- { before_install: *win_before_install, language: sh, python: "3.6", os: windows, env: TOX_ENV=py36-django31 }
5256

5357
- { before_install: *win_before_install, language: sh, python: "3.7", os: windows, env: TOX_ENV=py37-django22 }
5458
- { before_install: *win_before_install, language: sh, python: "3.7", os: windows, env: TOX_ENV=py37-django30 }
59+
- { before_install: *win_before_install, language: sh, python: "3.7", os: windows, env: TOX_ENV=py37-django31 }
5560

5661
- { before_install: *win_before_install, language: sh, python: "3.8", os: windows, env: TOX_ENV=py38-django30 }
62+
- { before_install: *win_before_install, language: sh, python: "3.8", os: windows, env: TOX_ENV=py38-django31 }
5763

5864

5965

sql_server/pyodbc/creation.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import binascii
22
import os
33

4+
import django
45
from django.db.backends.base.creation import BaseDatabaseCreation
56

67

78
class DatabaseCreation(BaseDatabaseCreation):
9+
@property
10+
def cursor(self):
11+
if django.VERSION >= (3, 1):
12+
return self.connection._nodb_cursor
13+
14+
return self.connection._nodb_connection.cursor
815

916
def _destroy_test_db(self, test_database_name, verbosity):
1017
"""
@@ -14,7 +21,7 @@ def _destroy_test_db(self, test_database_name, verbosity):
1421
# ourselves. Connect to the previous database (not the test database)
1522
# to do so, because it's not allowed to delete a database while being
1623
# connected to it.
17-
with self.connection._nodb_connection.cursor() as cursor:
24+
with self.cursor() as cursor:
1825
to_azure_sql_db = self.connection.to_azure_sql_db
1926
if not to_azure_sql_db:
2027
cursor.execute("ALTER DATABASE %s SET SINGLE_USER WITH ROLLBACK IMMEDIATE"
@@ -36,7 +43,7 @@ def enable_clr(self):
3643
This function will not fail if current user doesn't have
3744
permissions to enable clr, and clr is already enabled
3845
"""
39-
with self._nodb_connection.cursor() as cursor:
46+
with self.cursor() as cursor:
4047
# check whether clr is enabled
4148
cursor.execute('''
4249
SELECT value FROM sys.configurations
@@ -86,7 +93,7 @@ def install_regex_clr(self, database_name):
8693

8794
self.enable_clr()
8895

89-
with self._nodb_connection.cursor() as cursor:
96+
with self.cursor() as cursor:
9097
for s in sql:
9198
cursor.execute(s)
9299

sql_server/pyodbc/features.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
2222
requires_literal_defaults = True
2323
requires_sqlparse_for_splitting = False
2424
supports_boolean_expr_in_select_clause = False
25+
supports_deferrable_unique_constraints = False
2526
supports_ignore_conflicts = False
2627
supports_index_on_text_field = False
2728
supports_paramstyle_pyformat = False

sql_server/pyodbc/operations.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import datetime
22
import uuid
33
import warnings
4+
import django
45

56
from django.conf import settings
67
from django.db.backends.base.operations import BaseDatabaseOperations
8+
from django.db.models import Exists, ExpressionWrapper
9+
from django.db.models.expressions import RawSQL
10+
from django.db.models.sql.where import WhereNode
711
from django.utils import timezone
812
from django.utils.encoding import force_str
913

@@ -440,3 +444,18 @@ def time_trunc_sql(self, lookup_type, field_name):
440444
elif lookup_type == 'second':
441445
sql = "CONVERT(time, SUBSTRING(CONVERT(varchar, %s, 114), 0, 9))" % field_name
442446
return sql
447+
448+
def conditional_expression_supported_in_where_clause(self, expression):
449+
"""
450+
Following "Moved conditional expression wrapping to the Exact lookup" in django 3.1
451+
https://github.com/django/django/commit/37e6c5b79bd0529a3c85b8c478e4002fd33a2a1d
452+
"""
453+
if django.VERSION >= (3, 1):
454+
if isinstance(expression, (Exists, WhereNode)):
455+
return True
456+
if isinstance(expression, ExpressionWrapper) and expression.conditional:
457+
return self.conditional_expression_supported_in_where_clause(expression.expression)
458+
if isinstance(expression, RawSQL) and expression.conditional:
459+
return True
460+
return False
461+
return True

sql_server/pyodbc/schema.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,13 +694,15 @@ def create_unique_name(*args, **kwargs):
694694
name=name,
695695
columns=columns,
696696
condition=' WHERE ' + condition,
697+
deferrable=''
697698
) if self.connection.features.supports_partial_indexes else None
698699
else:
699700
return Statement(
700701
self.sql_create_unique,
701702
table=table,
702703
name=name,
703704
columns=columns,
705+
deferrable=''
704706
)
705707

706708
def _create_index_sql(self, model, fields, *, name=None, suffix='', using='',

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
envlist =
33
{py36,py37}-django22,
44
{py36,py37,py38}-django30,
5+
{py36,py37,py38}-django31,
56

67
[testenv]
78
passenv =
@@ -19,4 +20,5 @@ commands =
1920
deps =
2021
django22: django==2.2.*
2122
django30: django>=3.0a1,<3.1
23+
django31: django>=3.1,<3.2
2224
dj-database-url==0.5.0

0 commit comments

Comments
 (0)