0

I am trying to upgrade Django from 1.8 to 1.9 but, when I run migrations it's throwing up error. Below is the stack trace.

Stack trace

This is because of a new migration introduced in Django 1.9 which is to move auth username unicity logic from form to model [ref: ticket ]. But, before upgrading we have implemented a little hack mentioned here to increase username character length from the default 30 character length to 75 characters. Now, when I run migrations it's considering only the first 30 characters of username and throwing up Integrity Error. Is there a way around this ? I don't want to go for a custom auth model as there are lot of complications involved.

Community
  • 1
  • 1
Conans
  • 461
  • 1
  • 4
  • 14
  • Are there many users in the DB? – Andrey Shipilov Apr 04 '17 at 08:36
  • @AndreyShipilov Yes there are. – Conans Apr 04 '17 at 08:39
  • One harsh option would be to get those duplicate usernames, change all of them to something unique, say, by adding a number at the end. Then migrate, then change them back. – Andrey Shipilov Apr 04 '17 at 08:40
  • You could try faking from `0006_require_contenttypes_0002` to `0007_alter_validators_add_error_messages`. That will prevent `migrate` from giving errors, but you may encounter other problems. – Alasdair Apr 04 '17 at 08:41
  • Yeah, or that what @Alasdair proposed. – Andrey Shipilov Apr 04 '17 at 08:41
  • @AndreyShipilov They are not duplicates. It's considering only the first 30 characters and complaining that they are duplicate. Ex: testuserinternal_azure20131218@test.com, testuserinternal_azure20131218_1@test.com. – Conans Apr 04 '17 at 08:46
  • In this case, yeah. Just fake migrate to 0007. – Andrey Shipilov Apr 04 '17 at 08:46
  • @Alasdair I am sure faking the migration will trouble me going forward. Can you think of any other solution ? – Conans Apr 04 '17 at 08:53
  • Note also that if you can upgrade to Django 1.10, then [the max length of the username is increased to 150](https://docs.djangoproject.com/en/1.10/releases/1.10/#abstractuser-username-max-length-increased-to-150). If your code runs in Django 1.8 without deprecation warnings, then the upgrade to Django 1.10 should be straight forward and you can skip 1.9. – Alasdair Apr 04 '17 at 08:53
  • @Alasdair Yeah I came across this change but my code has lot of deprecation warnings which should be fixed to be upgraded to 1.10. – Conans Apr 04 '17 at 08:55
  • I would stick with Django 1.8 until you fix the deprecation warnings, then upgrade straight to 1.10 (or 1.11 LTS when it's released) and fake migration 0007. That way you can remove any username length hacks that might cause you trouble. If you start any other Django projects in future, always use a custom auth model to avoid issues like this. It's very late in the release cycle to upgrade to 1.9.x, it won't be supported after 1.11 is released this month, but 1.8.x LTS will be supported until April 2018. – Alasdair Apr 04 '17 at 08:59
  • @Alasdair Okay. Thanks for your inputs, one question though, should I still fake migration 0007 if I upgrade to 1.10 ? No, right ? – Conans Apr 04 '17 at 09:04
  • Yes, you still have to fake migration 0007. It is trying to change the column from 75 characters to 30. Even if duplicates were't an issue, you wouldn't want `testuserinternal_azure20131218@test.com` to be truncated to `testuserinternal_azure20131218` (whether the long usernames cause an error or are silently truncated probably depends on your database engine). – Alasdair Apr 04 '17 at 09:15

1 Answers1

0

First, migrate to migration 0006 if you haven't already.

./manage.py migrate auth 0006_require_contenttypes_0002

Then upgrade to Django 1.10 (or 1.11 LTS) once it's released, and fake migration 0007.

./manage.py migrate auth 0007_alter_validators_add_error_messages --fake

This migration is trying to reduce the column from 75 characters to 30 characters, so it must be faked.

Then, you can run the rest of the migrations for auth:

./manage.py migrate auth

In particular, migration 0008 from Django 1.10 will increase the max length of the username to 150 characters. This means you can remove any hacks to alter the username max length that could cause problems.

To be on the safe side, I wouldn't recommend faking 0007 and upgrading to Django 1.9. I have no idea whether faking the migration and keeping your username length hack would work or cause problems I haven't thought of.

Alasdair
  • 298,606
  • 55
  • 578
  • 516