#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.

Reply via email to