Skip to content

FEAT: Support 5.2- Added composite primary key #462

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions mssql/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

from django.db.backends.base.features import BaseDatabaseFeatures
from django.utils.functional import cached_property


from django import VERSION as django_version
# Import CompositePrimaryKey only if Django version is 5.2 or higher
if django_version >= (5, 2):
from django.db.models.fields.composite import CompositePrimaryKey
class DatabaseFeatures(BaseDatabaseFeatures):
allows_group_by_select_index = False
allow_sliced_subqueries_with_in = False
Expand Down Expand Up @@ -63,8 +65,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_default_keyword_in_bulk_insert = True
supports_stored_generated_columns = True
supports_virtual_generated_columns = True


# CompositePrimaryKey support is only available in Django 5.2 and later
supports_composite_primary_keys = django_version >= (5, 2)
if django_version >= (5, 2) and isinstance(CompositePrimaryKey, type):
# Set fallback tupple lookup support
Copy link
Preview

Copilot AI Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misspelling: 'tupple' should be corrected to 'tuple'.

Suggested change
# Set fallback tupple lookup support
# Set fallback tuple lookup support

Copilot uses AI. Check for mistakes.

supports_tuple_lookups = False
@cached_property
def has_zoneinfo_database(self):
with self.connection.cursor() as cursor:
Expand Down
22 changes: 19 additions & 3 deletions mssql/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
if django_version >= (4, 0):
from django.db.models.sql import Query
from django.db.backends.ddl_references import Expressions


# Import CompositePrimaryKey only if Django version is 5.2 or higher
if django_version >= (5, 2):
from django.db.models.fields.composite import CompositePrimaryKey
class Statement(DjStatement):
def __hash__(self):
return hash((self.template, str(self.parts['name'])))
Expand Down Expand Up @@ -1315,7 +1316,19 @@ def create_model(self, model):
autoinc_sql = self.connection.ops.autoinc_sql(model._meta.db_table, field.column)
if autoinc_sql:
self.deferred_sql.extend(autoinc_sql)


# Initialize composite_pk_sql to None; will be set if composite primary key is detected
composite_pk_sql = None
# Check if Django version is >= 5.2 and the model has composite primary key fields
if django_version >= (5, 2) and hasattr(model._meta, "pk_fields"):
#specifically refers to the primary key field of that model.
pk = model._meta.pk
# Check if the primary key is a CompositePrimaryKey instance
if isinstance(pk, CompositePrimaryKey):
# Get the column names for all fields in the composite primary key
pk_columns = [field.column for field in model._meta.pk_fields]
# Build the PRIMARY KEY SQL clause for the composite key
composite_pk_sql = "PRIMARY KEY (%s)" % ", ".join(self.quote_name(col) for col in pk_columns)
# Add any unique_togethers (always deferred, as some fields might be
# created afterwards, like geometry fields with some backends)
for field_names in model._meta.unique_together:
Expand All @@ -1328,6 +1341,9 @@ def create_model(self, model):
self.deferred_sql.append(self._create_unique_sql(model, columns, condition=condition))

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