Auth Migrations over multiple devices

Hi everyone,

I’m currently facing a rather tricky issue with Django migrations and would appreciate any insights or advice.

The Setup:

I work on a Django project and use Git for version control. On my local machine, I run a Virtual Python Environment where I’ve installed all the required dependencies. I’ve read that it’s a good practice to have all my own migration files versioned in Git since they precisely document the evolution of my database schema.

The Situation:

On my primary computer, I’ve been regularly updating Python and Django over time. As a result, new migrations for Django’s built-in auth app were generated repeatedly—for instance, a migration that alters the first_name field from 30 to 150 characters (specifically, the 0012_alter_user_first_name_max_length migration). These migration files are part of the installed Django package in my virtual environment and are not included in my Git repo.

Now, I’ve cloned this Git repo on another computer and installed all the dependencies from the requirements.txt file. Both systems are configured to use the same MySQL database over the network. However, on the new system, only the initial migration files exist—where the final state of the models is defined directly—without the step-by-step migration history that evolved on my primary computer.

When I try to run the project, I encounter the following error:

raise NodeNotFoundError(self.error_message, self.key, origin=self.origin)
django.db.migrations.exceptions.NodeNotFoundError: Migration api.0001_initial dependencies reference nonexistent parent node ('auth', '0012_alter_user_first_name_max_length')

In plain terms, this means that on my main computer, due to Django updates, an auth migration (namely 0012_alter_user_first_name_max_length) was generated, while on the new system that migration file doesn’t exist. Consequently, one of my own migrations in the API app references a migration node (auth.0012_alter_user_first_name_max_length) that isn’t present on the new machine.

My Question:

How can I handle this scenario? It should be possible for the same Django project to run on multiple systems without encountering such migration errors. I would be thankful for any suggestions or solutions to resolve these dependency discrepancies.

Thanks everyone,
Alex

Welcome @mustermannalex !

The official django.contrib.auth.migrations package has all the migration files. If you don’t have them in your installed Django instance, then you’re doing something wrong with your virtual environment.

You should not be in this situation.

Now, if what you’re saying is that you haven’t upgraded this second instance of Django, that’s a different problem. What you want to do is upgrade that second version of Django to match the first. (After all, it’s possible that your code may depend upon features or facilities present in the newer version - there’s no immediate guarantee that it will work with the older version.)

Thank you for your explanation. I’ve double-checked that both of my Django environments are running the latest version, so I’m confident they should include all the official migration files in django.contrib.auth.migrations.

My assumption was that this package would contain everything I need, and I wouldn’t have to manage anything extra. However, I’m a bit puzzled because I see additional migration dependencies referenced by my own migrations. I had assumed that these extra migrations originated from Django updates, but I haven’t been able to verify exactly where they’re coming from.

Where exactly do these additional migrations originate?
Is there any extra step I should take to ensure that my custom migrations correctly reference the official migrations?

For example, here’s a snippet from my initial migration for database creation. In this snippet, migration 0012_alter_user_first_name_max_length is referenced, but on another instance this migration does not exist:

class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('api', '0001_initial'),
        ('auth', '0012_alter_user_first_name_max_length'),
    ]

Is it possible that I created these migrations with my code? It seems odd to me because I did not manually increase the first_name field to 150 characters, as the 0012 migration indicates.

I am indeed using a custom user model that inherits from AbstractUser, but I didn’t think that could be the issue, isn’t it?

class MYCUSTOMUser(AbstractUser):
    #All Users:
    id = models.CharField(primary_key=True, max_length=26,default=generate_ulid,editable=False)
    username = None
    email = models.EmailField(max_length=254, unique=True)
    title = models.ForeignKey(UserAcademicTitle, verbose_name="UserAcademicTitle", on_delete=models.SET_NULL, null=True, blank=True)

It could, if you haven’t managed the creation and usage of your custom user model correctly.

You will have problems if you started one version of the project with the default User and then switched to your custom model later.

See the section of the docs starting with Substituting a custom user model

I’ve made sure not to change the user model during the process. My project is still in development, so I frequently delete and recreate my database to eliminate errors before going into production. To do this, I’ve deleted migration files and completely recreated the database using makemigrations and migrate.

Could this be causing the issue? If so, how can I restore a stable version? Should I delete my virtual environment and reinstall it, or is there another way to resolve the error? Also, how do you generally port a Django project to another instance? Do I need to copy the virtual environment over, or is it sufficient to create a new one and install all the required packages paired with my git repo?

This isn’t a problem. The problems are caused by starting a project with the default User model, and then changing to a custom model after the first migration has been applied.

If you start your project with a custom user model, then you can change it as desired during the development process.

Don’t ever do this when you’re going to deploy this to an environment with an existing database. (In other words, if you do this on system “A”, then make sure you also drop the database and recreate it on system “B”.)

The easiest way is to drop the database and recreate it. (Yes, it can be “fixed”, but it’s a manual process that isn’t exactly trivial.)

Your virtual environment has nothing to do with this. This is strictly an issue between your code and your database.

It’s not a “port”, it’s a copy. Done properly, there’s no work to be done on the code outside the settings file. I copy the project, run pip install -r requirements.txt, and migrate.