#37006: Attempting to recreate the PK in a model with no other fields generates a
migration that crashes on SQLite
-------------------------------------+-------------------------------------
Reporter: Carol Naranjo | Type: Bug
Status: new | Component: Database
| layer (models, ORM)
Version: 6.0 | Severity: Normal
Keywords: sqlite, migrations | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
When a model contains no fields other than the primary key, and the PK is
recreated (e.g., renaming and switching from an AutoField to a UUIDField),
Django generates a migration with two operations: RemoveField followed by
AddField.
In SQLite, applying this migration fails because SQLite cannot create a
table with no columns. It only affects SQLite because in other databases
the table can be altered by droping the column, whereas SQLite requires
that a new table is created and then the data is copied.
**Steps to reproduce:**
1. Starting with a model with only the primary key:
{{{
class Place(models.Model):
pass # PK is created by default as AutoField with column name "id"
}}}
2. Modify the primary key:
{{{
class Place(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4,
editable=False)
}}}
3. Run `makemigrations`. Which generates following migration:
{{{
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='place',
name='id',
),
migrations.AddField(
model_name='place',
name='uid',
field=models.AutoField(primary_key=True, serialize=False),
),
]
}}}
4. Apply the migration using SQLite.
**Observed behavior:**
During the RemoveField operation, the generated migration tries to create
a table with zero non-PK columns, resulting in:
{{{
CREATE TABLE "new__myapp_place" (); (params None)
sqlite3.OperationalError: near ")": syntax error
}}}
**Expected behavior:**
SQLite migration should not crash. Either prevent a migration that would
create a table with zero columns or handle it gracefully.
**On a side note**: This is an edge case—tables without additional fields
are rare—but it still causes an unexpected crash.
--
Ticket URL: <
https://code.djangoproject.com/ticket/37006>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.