Skip to content

Commit 78a78aa

Browse files
mShan0dauinsight
andauthored
Django 5.0 support (#327)
* basic 5.0 support * use django main branch * use alpha 5.0 branch * preliminary fix for nulls_distinct * add _unique_supported function * Fix schema db default test * Skip constraint tests * Support db_default field * Remove operations test fixes * Preliminary fix * Check version before accessing db_default * Skip add field database default test * Update returned values from insert * Change can_return_rows_from_bulk_insert default to True * Revert format sql changes * Prevent formatting empty params query * unskip add_field_database_default * fix add_field_both_defaults test * Update nullable default field behavior * update odbc 17 windows ci * reduce tox tests for testing purposes * bump tox version to 5.0 * add field_defaults * Fix default constraints test * unskip tox tests --------- Co-authored-by: Daniel Au (SIMBA TECHNOLOGIES INC) <v-audaniel@microsoft.com> Co-authored-by: dauinsight <145612907+dauinsight@users.noreply.github.com>
1 parent bded2ce commit 78a78aa

File tree

8 files changed

+225
-29
lines changed

8 files changed

+225
-29
lines changed

azure-pipelines.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ jobs:
2424

2525
strategy:
2626
matrix:
27+
Python3.12 - Django 5.0:
28+
python.version: '3.12'
29+
tox.env: 'py312-django50'
30+
Python3.11 - Django 5.0:
31+
python.version: '3.11'
32+
tox.env: 'py311-django50'
33+
Python3.10 - Django 5.0:
34+
python.version: '3.10'
35+
tox.env: 'py310-django50'
36+
2737
Python3.11 - Django 4.2:
2838
python.version: '3.11'
2939
tox.env: 'py311-django42'
@@ -92,7 +102,7 @@ jobs:
92102
93103
(Get-Content $pwd/testapp/settings.py).replace('localhost', $IP) | Set-Content $pwd/testapp/settings.py
94104
95-
Invoke-WebRequest https://download.microsoft.com/download/E/6/B/E6BFDC7A-5BCD-4C51-9912-635646DA801E/en-US/17.5.2.1/x64/msodbcsql.msi -OutFile msodbcsql.msi
105+
Invoke-WebRequest https://download.microsoft.com/download/6/f/f/6ffefc73-39ab-4cc0-bb7c-4093d64c2669/en-US/17.10.5.1/x64/msodbcsql.msi -OutFile msodbcsql.msi
96106
msiexec /quiet /passive /qn /i msodbcsql.msi IACCEPTMSODBCSQLLICENSETERMS=YES
97107
Get-OdbcDriver
98108
displayName: Install ODBC
@@ -131,6 +141,16 @@ jobs:
131141

132142
strategy:
133143
matrix:
144+
Python3.12 - Django 5.0:
145+
python.version: '3.12'
146+
tox.env: 'py312-django50'
147+
Python3.11 - Django 5.0:
148+
python.version: '3.11'
149+
tox.env: 'py311-django50'
150+
Python3.10 - Django 5.0:
151+
python.version: '3.10'
152+
tox.env: 'py310-django50'
153+
134154
Python3.11 - Django 4.2:
135155
python.version: '3.11'
136156
tox.env: 'py311-django42'

mssql/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ def format_sql(self, sql, params):
581581
sql = smart_str(sql, self.driver_charset)
582582

583583
# pyodbc uses '?' instead of '%s' as parameter placeholder.
584-
if params is not None:
584+
if params is not None and params != []:
585585
sql = sql % tuple('?' * len(params))
586586

587587
return sql

mssql/features.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
1313
can_introspect_small_integer_field = True
1414
can_return_columns_from_insert = True
1515
can_return_id_from_insert = True
16-
can_return_rows_from_bulk_insert = False
16+
can_return_rows_from_bulk_insert = True
1717
can_rollback_ddl = True
1818
can_use_chunked_reads = False
1919
for_update_after_from = True
@@ -57,6 +57,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
5757
supports_partially_nullable_unique_constraints = True
5858
supports_partial_indexes = True
5959
supports_functions_in_partial_indexes = True
60+
supports_default_keyword_in_insert = True
61+
supports_expression_defaults = True
62+
supports_default_keyword_in_bulk_insert = True
6063

6164
@cached_property
6265
def has_zoneinfo_database(self):

mssql/introspection.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ def get_table_description(self, cursor, table_name, identity_check=True):
164164
column[1] = SQL_AUTOFIELD
165165
if column[1] == Database.SQL_WVARCHAR and column[3] < 4000:
166166
column[1] = Database.SQL_WCHAR
167+
# Remove surrounding parentheses for default values
168+
if column[7]:
169+
default_value = column[7]
170+
start = 0
171+
end = -1
172+
for _ in range(2):
173+
if default_value[start] == '(' and default_value[end] == ')':
174+
start += 1
175+
end -= 1
176+
column[7] = default_value[start:end + 1]
177+
167178
if VERSION >= (4, 2):
168179
items.append(FieldInfo(*column))
169180
else:
@@ -304,6 +315,7 @@ def get_constraints(self, cursor, table_name):
304315
# Potentially misleading: primary key and unique constraints still have indexes attached to them.
305316
# Should probably be updated with the additional info from the sys.indexes table we fetch later on.
306317
"index": False,
318+
"default": False,
307319
}
308320
# Record the details
309321
constraints[constraint]['columns'].append(column)
@@ -331,6 +343,32 @@ def get_constraints(self, cursor, table_name):
331343
"foreign_key": None,
332344
"check": True,
333345
"index": False,
346+
"default": False,
347+
}
348+
# Record the details
349+
constraints[constraint]['columns'].append(column)
350+
# Now get DEFAULT constraint columns
351+
cursor.execute("""
352+
SELECT
353+
[name],
354+
COL_NAME([parent_object_id], [parent_column_id])
355+
FROM
356+
[sys].[default_constraints]
357+
WHERE
358+
OBJECT_NAME([parent_object_id]) = %s
359+
""", [table_name])
360+
for constraint, column in cursor.fetchall():
361+
# If we're the first column, make the record
362+
if constraint not in constraints:
363+
constraints[constraint] = {
364+
"columns": [],
365+
"primary_key": False,
366+
"unique": False,
367+
"unique_constraint": False,
368+
"foreign_key": None,
369+
"check": False,
370+
"index": False,
371+
"default": True,
334372
}
335373
# Record the details
336374
constraints[constraint]['columns'].append(column)
@@ -374,6 +412,7 @@ def get_constraints(self, cursor, table_name):
374412
"unique_constraint": unique_constraint,
375413
"foreign_key": None,
376414
"check": False,
415+
"default": False,
377416
"index": True,
378417
"orders": [],
379418
"type": Index.suffix if type_ in (1, 2) else desc.lower(),

0 commit comments

Comments
 (0)