mirror of
https://github.com/django/django.git
synced 2025-06-03 02:29:13 +00:00
[5.2.x] 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. Backport of 07100db6f46255ec6ef70b860495f977473684d6 from main.
This commit is contained in:
parent
5d03c71b7a
commit
ec73fd6746
@ -115,7 +115,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
).fetchone()
|
).fetchone()
|
||||||
if has_json_constraint:
|
if has_json_constraint:
|
||||||
json_columns.add(column)
|
json_columns.add(column)
|
||||||
return [
|
table_description = [
|
||||||
FieldInfo(
|
FieldInfo(
|
||||||
name,
|
name,
|
||||||
data_type,
|
data_type,
|
||||||
@ -126,7 +126,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
not notnull,
|
not notnull,
|
||||||
default,
|
default,
|
||||||
collations.get(name),
|
collations.get(name),
|
||||||
pk == 1,
|
bool(pk),
|
||||||
name in json_columns,
|
name in json_columns,
|
||||||
)
|
)
|
||||||
for cid, name, data_type, notnull, default, pk, hidden in table_info
|
for cid, name, data_type, notnull, default, pk, hidden in table_info
|
||||||
@ -137,6 +137,15 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||||||
3, # Stored generated column.
|
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=()):
|
def get_sequences(self, cursor, table_name, table_fields=()):
|
||||||
pk_col = self.get_primary_key_column(cursor, table_name)
|
pk_col = self.get_primary_key_column(cursor, table_name)
|
||||||
|
@ -55,3 +55,7 @@ Bugfixes
|
|||||||
* Fixed a regression in Django 5.2 that caused a crash when using ``update()``
|
* 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
|
on a ``QuerySet`` filtered against a related model and including references
|
||||||
to annotations through ``values()`` (:ticket:`36360`).
|
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`).
|
||||||
|
@ -628,10 +628,7 @@ class InspectDBTransactionalTests(TransactionTestCase):
|
|||||||
|
|
||||||
def test_composite_primary_key(self):
|
def test_composite_primary_key(self):
|
||||||
out = StringIO()
|
out = StringIO()
|
||||||
if connection.vendor == "sqlite":
|
field_type = connection.features.introspected_field_types["IntegerField"]
|
||||||
field_type = connection.features.introspected_field_types["AutoField"]
|
|
||||||
else:
|
|
||||||
field_type = connection.features.introspected_field_types["IntegerField"]
|
|
||||||
call_command("inspectdb", "inspectdb_compositeprimarykeymodel", stdout=out)
|
call_command("inspectdb", "inspectdb_compositeprimarykeymodel", stdout=out)
|
||||||
output = out.getvalue()
|
output = out.getvalue()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
@ -639,8 +636,4 @@ class InspectDBTransactionalTests(TransactionTestCase):
|
|||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
self.assertIn(f"column_1 = models.{field_type}()", output)
|
self.assertIn(f"column_1 = models.{field_type}()", output)
|
||||||
self.assertIn(
|
self.assertIn(f"column_2 = models.{field_type}()", output)
|
||||||
"column_2 = models.%s()"
|
|
||||||
% connection.features.introspected_field_types["IntegerField"],
|
|
||||||
output,
|
|
||||||
)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user