Currently Django 3.2 and Django 4.2 are LTS releases. As a maintainer on django-taggit
, I try to support all of this across the board unless I really have a reason not to.
I want to preface this a bit by saying I obviously could have brought this up way earlier, but I hadn’t fully put the pieces together until today.
Django 4.2 reports a deprecation on index_together
, suggesting instead to use indexes
. Great.
index_together
names the index in a DB-dependent way. This means that I can’t “just” hardcode the old name into migrations (that run across multiple machines). New Index
objects demands a name. So if I want to update my migration file to use AddIndex
for new deployments, I’m now hardcoding a “fake” name.
And of course we have migrations.RenameIndex
as a nice helper. It can query the DB based on the field tuple to find the index (this doesn’t work if you’re using an in-memory DB, but that’s magic for you). RenameIndex
does all this querying to figure out what the old index name is for a rename.
But RenameIndex
is not available in Django 3.2. And the logic is subtle enough that I do not believe I can reproduce it well.
I would like to stop using deprecated stuff in 4.2 (and users have been complaining about this deprecation issue), but I have three options:
- Tell Django 3.2 users “do the operation manually” while I ship a
RenameIndex
migration that only works in 4.x - Hold off on clearing these deprecation warnings until early 2024, Meanwhile this makes it harder for me to look at Django
main
- Remove support for 3.2 entirely (what I think I’m going to do here so I can move forward)
This is the first time in a really long time I felt like I couldn’t have my cake and eat it too regarding Django upgrades. I’ve usually felt like that (with some django version checks) I’ve always had a clean upgrade path that “just works”.
Here there’s the “original sin” of index_together
not holding onto the index name in the migrations, but part of the cure for this (RenameIndex
) ending up not being available in 3.2 was annoying.
I totally get wanting to get things onto deprecation paths, and I understand this case is super specific. But I wanted to share this as I spent a couple hours thinking about what is best here. In my magical ideal world, when a deprecation warning shows up, I should be able to update a library to no longer have that deprecation warning, ship across all supported Django releases at the time, and have as few django.VERSION
checks as possible.
TL;DR: “remove index_together
” implies "use indexes
(and AddIndex(..., name=thing-that-was-db-dependent-that-no-longer-is)
.
This also implies using RenameIndex
to actually get the index to be named the same across all environments in a new migration
When 4.2 deprecated index_together
, 3.2 was still in the support window, but missed RenameIndex
as a tool. This made it hard to go to 4.2
without simultaenously dropping support for 3.2
for reasons that felt incidental.
Thanks to everyone who works on this stuff, migrations are a nightmare to work on just at a conceptual level. And I know things are so much better than they used to be!