Skip to content

Commit 97ba852

Browse files
committed
added composite primary key support
1 parent 07bee47 commit 97ba852

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

mssql/features.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
from django.db.backends.base.features import BaseDatabaseFeatures
55
from django.utils.functional import cached_property
6-
7-
6+
from django import VERSION as django_version
7+
# Import CompositePrimaryKey only if Django version is 5.2 or higher
8+
if django_version >= (5, 2):
9+
from django.db.models.fields.composite import CompositePrimaryKey
810
class DatabaseFeatures(BaseDatabaseFeatures):
911
allows_group_by_select_index = False
1012
allow_sliced_subqueries_with_in = False
@@ -63,8 +65,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
6365
supports_default_keyword_in_bulk_insert = True
6466
supports_stored_generated_columns = True
6567
supports_virtual_generated_columns = True
66-
67-
68+
# CompositePrimaryKey support is only available in Django 5.2 and later
69+
supports_composite_primary_keys = django_version >= (5, 2)
70+
if django_version >= (5, 2) and isinstance(CompositePrimaryKey, type):
71+
# Set fallback tupple lookup support
72+
supports_tuple_lookups = False
6873
@cached_property
6974
def has_zoneinfo_database(self):
7075
with self.connection.cursor() as cursor:

mssql/schema.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@
2929
if django_version >= (4, 0):
3030
from django.db.models.sql import Query
3131
from django.db.backends.ddl_references import Expressions
32-
33-
32+
# Import CompositePrimaryKey only if Django version is 5.2 or higher
33+
if django_version >= (5, 2):
34+
from django.db.models.fields.composite import CompositePrimaryKey
3435
class Statement(DjStatement):
3536
def __hash__(self):
3637
return hash((self.template, str(self.parts['name'])))
@@ -1315,7 +1316,19 @@ def create_model(self, model):
13151316
autoinc_sql = self.connection.ops.autoinc_sql(model._meta.db_table, field.column)
13161317
if autoinc_sql:
13171318
self.deferred_sql.extend(autoinc_sql)
1318-
1319+
1320+
# Initialize composite_pk_sql to None; will be set if composite primary key is detected
1321+
composite_pk_sql = None
1322+
# Check if Django version is >= 5.2 and the model has composite primary key fields
1323+
if django_version >= (5, 2) and hasattr(model._meta, "pk_fields"):
1324+
#specifically refers to the primary key field of that model.
1325+
pk = model._meta.pk
1326+
# Check if the primary key is a CompositePrimaryKey instance
1327+
if isinstance(pk, CompositePrimaryKey):
1328+
# Get the column names for all fields in the composite primary key
1329+
pk_columns = [field.column for field in model._meta.pk_fields]
1330+
# Build the PRIMARY KEY SQL clause for the composite key
1331+
composite_pk_sql = "PRIMARY KEY (%s)" % ", ".join(self.quote_name(col) for col in pk_columns)
13191332
# Add any unique_togethers (always deferred, as some fields might be
13201333
# created afterwards, like geometry fields with some backends)
13211334
for field_names in model._meta.unique_together:
@@ -1328,6 +1341,9 @@ def create_model(self, model):
13281341
self.deferred_sql.append(self._create_unique_sql(model, columns, condition=condition))
13291342

13301343
constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
1344+
# If a composite primary key SQL clause was generated, insert it at the beginning of the constraints list
1345+
if composite_pk_sql:
1346+
constraints.insert(0, composite_pk_sql)
13311347
# Make the table
13321348
sql = self.sql_create_table % {
13331349
"table": self.quote_name(model._meta.db_table),

0 commit comments

Comments
 (0)