Repository: django/django
Issue category: Feature Request

Add support for CompositePrimaryKey in inspectdb
Description
	 
We can now replace the ​half-measure created when introspecting a composite primary key with the actual field.
​PR


Functions to edit:
django/core/management/commands/inspectdb.py:Command.handle_inspection

Patch:
diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py
index 77605b178f69..58594fb66f80 100644
--- a/django/core/management/commands/inspectdb.py
+++ b/django/core/management/commands/inspectdb.py
@@ -106,9 +106,12 @@ def handle_inspection(self, options):
                         connection.introspection.get_primary_key_columns(
                             cursor, table_name
                         )
+                        or []
                     )
                     primary_key_column = (
-                        primary_key_columns[0] if primary_key_columns else None
+                        primary_key_columns[0]
+                        if len(primary_key_columns) == 1
+                        else None
                     )
                     unique_columns = [
                         c["columns"][0]
@@ -128,6 +131,11 @@ def handle_inspection(self, options):
                 yield ""
                 yield "class %s(models.Model):" % model_name
                 known_models.append(model_name)
+
+                if len(primary_key_columns) > 1:
+                    fields = ", ".join([f"'{col}'" for col in primary_key_columns])
+                    yield f"    pk = models.CompositePrimaryKey({fields})"
+
                 used_column_names = []  # Holds column names used in the table so far
                 column_to_field_name = {}  # Maps column names to names of model fields
                 used_relations = set()  # Holds foreign relations used in the table.
@@ -151,12 +159,6 @@ def handle_inspection(self, options):
                     # Add primary_key and unique, if necessary.
                     if column_name == primary_key_column:
                         extra_params["primary_key"] = True
-                        if len(primary_key_columns) > 1:
-                            comment_notes.append(
-                                "The composite primary key (%s) found, that is not "
-                                "supported. The first column is selected."
-                                % ", ".join(primary_key_columns)
-                            )
                     elif column_name in unique_columns:
                         extra_params["unique"] = True
 

Test patch: diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py
index 1be4efc43051..131bd45ce89e 100644
--- a/tests/inspectdb/tests.py
+++ b/tests/inspectdb/tests.py
@@ -655,11 +655,10 @@ def test_composite_primary_key(self):
             call_command("inspectdb", table_name, stdout=out)
             output = out.getvalue()
             self.assertIn(
-                f"column_1 = models.{field_type}(primary_key=True)  # The composite "
-                f"primary key (column_1, column_2) found, that is not supported. The "
-                f"first column is selected.",
+                "pk = models.CompositePrimaryKey('column_1', 'column_2')",
                 output,
             )
+            self.assertIn(f"column_1 = models.{field_type}()", output)
             self.assertIn(
                 "column_2 = models.%s()"
                 % connection.features.introspected_field_types["IntegerField"],