#31765: schema.tests.SchemaTests.test_db_table fails on MacOS
-------------------------------------+-------------------------------------
Reporter: Tom Forbes | Owner: Tom
| Forbes
Type: Bug | Status: closed
Component: Database layer | Version: dev
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Andy Chosak):
Unfortunately the unit test failure described above is pointing out that
`RenameModel` migrations won't properly repoint foreign keys when run
against certain versions of SQLite on MacOS. This interferes with testing
and developing using model renames on MacOS with currently supported
versions of Django -- please see
https://github.com/wagtail/wagtail/issues/8635 for a specific example.
I see this error (both the unit test failure and the incorrect model
rename behavior) on MacOS 11.6.5 with its default SQLite3 version 3.32.3.
Digging into the (long!) history of Django changes to support SQLite
`ALTER TABLE` statements, the relevant technical detail here seem to be my
SQLite pragma defaults of `foreign_keys=0` and `legacy_alter_table=1`.
Per the SQLite docs
[https://www.sqlite.org/draft/lang_altertable.html#alter_table_rename
here], these pragma values mean that parent table references are **not**
automatically updated.
This issue first came up in #29182, which resulted in a proposed fix in
53b17d4734f06372b66e3ac4db7a1740c503b330.
This was then updated in #30033 to try to comply with an alternate
procedure for `ALTER TABLE` documented
[https://www.sqlite.org/lang_altertable.html#otheralter here]. This was
implemented in 7289874adceec46b5367ec3157cdd10c711253a0, but, notably,
this alternate procedure isn't followed for regular table renames, but
only for
[https://github.com/django/django/blob/3.2.13/django/db/backends/sqlite3/schema.py#L142-L157
""non-rename or column addition operations""]. So a standard `RenameModel`
still uses a standard `ALTER TABLE ... RENAME TO ...` which, if pragmas
are set as above, won't correctly repoint foreign keys.
I ''think'' that what all this might mean is that `RenameModel` foreign
key repointing was broken for a long time on versions of SQLite with
`foreign_keys=0` and `legacy_alter_table=1` (including versions 3.2 and
4.0). Commit 063cf98d3a6839f40c423cbd845def429c5cf0ce fixes that by always
setting `legacy_alter_table = OFF`, thus avoiding the bad configuration
even with simple `ALTER TABLE ... RENAME TO ...` statements.
Might it be possible to get this fix backported to currently supported
versions of Django?
(Another option might be to use the alternate procedure even for basic
table renames.)
--
Ticket URL: <https://code.djangoproject.com/ticket/31765#comment:20>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/010701813f3025aa-af30febe-f2d8-4fb5-a10a-8ef54ffb9e2e-000000%40eu-central-1.amazonses.com.