1
0
mirror of https://github.com/django/django.git synced 2025-06-02 01:59:11 +00:00

Fixed #36358 -- Corrected introspection of composite primary keys on SQLite.

Previously, any first field of a composite primary key with type
`INTEGER` was incorrectly introspected as an `AutoField` due to SQLite
treating `INTEGER PRIMARY KEY` as an alias for the `ROWID`.

This change ensures that integer fields in composite PKs are not
mistaken for auto-incrementing fields.

Thanks Jacob Walls and Sarah Boyce for the reviews.
This commit is contained in:
Simon Charette 2025-04-28 23:35:04 -04:00 committed by nessita
parent 4c75858135
commit 07100db6f4
3 changed files with 17 additions and 11 deletions

View File

@ -115,7 +115,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
).fetchone()
if has_json_constraint:
json_columns.add(column)
return [
table_description = [
FieldInfo(
name,
data_type,
@ -126,7 +126,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
not notnull,
default,
collations.get(name),
pk == 1,
bool(pk),
name in json_columns,
)
for cid, name, data_type, notnull, default, pk, hidden in table_info
@ -137,6 +137,15 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
3, # Stored generated column.
]
]
# If the primary key is composed of multiple columns they should not
# be individually marked as pk.
primary_key = [
index for index, field_info in enumerate(table_description) if field_info.pk
]
if len(primary_key) > 1:
for index in primary_key:
table_description[index] = table_description[index]._replace(pk=False)
return table_description
def get_sequences(self, cursor, table_name, table_fields=()):
pk_col = self.get_primary_key_column(cursor, table_name)

View File

@ -55,3 +55,7 @@ Bugfixes
* Fixed a regression in Django 5.2 that caused a crash when using ``update()``
on a ``QuerySet`` filtered against a related model and including references
to annotations through ``values()`` (:ticket:`36360`).
* Fixed a bug in composite primary key introspection that caused
``IntegerField`` to be wrongly identified as ``AutoField`` on SQLite
(:ticket:`36358`).

View File

@ -628,10 +628,7 @@ class InspectDBTransactionalTests(TransactionTestCase):
def test_composite_primary_key(self):
out = StringIO()
if connection.vendor == "sqlite":
field_type = connection.features.introspected_field_types["AutoField"]
else:
field_type = connection.features.introspected_field_types["IntegerField"]
field_type = connection.features.introspected_field_types["IntegerField"]
call_command("inspectdb", "inspectdb_compositeprimarykeymodel", stdout=out)
output = out.getvalue()
self.assertIn(
@ -639,8 +636,4 @@ class InspectDBTransactionalTests(TransactionTestCase):
output,
)
self.assertIn(f"column_1 = models.{field_type}()", output)
self.assertIn(
"column_2 = models.%s()"
% connection.features.introspected_field_types["IntegerField"],
output,
)
self.assertIn(f"column_2 = models.{field_type}()", output)