Good day, community. There was a problem with database migrations when porting an already finished Django 1.11.2 project to a combat VDS (Debian 8 x64, nginx, PostgreSQL 9.6).

The table itself is empty in the database, the settings.py for the connection are specified in settings.py (and tested). The structure of the project is quite simple - three applications: myproject (initial, where settings), clients and citizenship .

At the same time, the model from the citizenship is the ForeignKey field for the model from the clients . The model from clients , in turn, is used as AUTH_USER_MODEL .

citizenship / models.py

 class Citizenship(models.Model): """ Citizenship model """ name = models.CharField(_('Country name'), max_length=55, unique=True) is_active = models.BooleanField(default=True) is_available_for_order = models.BooleanField(default=True) class Meta: verbose_name = 'Citizenship' verbose_name_plural = 'Citizenship' def __str__(self): # Display model output like `USA` return '{}'.format(self.name) 

clients / models.py

 class Client(AbstractUser, PermissionsMixin): """ Client model """ email = models.EmailField(_('E-mail'), unique=True) first_name = models.CharField(_('First name'), max_length=155, blank=False) middle_name = models.CharField(_('Middle name'), max_length=155, blank=True) last_name = models.CharField(_('Last name'), max_length=155, blank=False) gender = models.IntegerField(_('Gender'), choices=GENDER, default=0) # add relationship to `Citizenship` model citizenship = models.ForeignKey(Citizenship, on_delete=None, null=True) birthday = models.DateField(_('Birthday'), blank=False, null=True) visa_start_date = models.DateField(_('Visa start date'), blank=True, null=True) visa_end_date = models.DateField(_('Visa end date'), blank=True, null=True) # upload passport copy to ./upload/YEAR/MONTH/DAY folder passport_copy = models.ImageField( _('Passport copy'), validators=[validate_image_extension], upload_to='docs/%Y/%m/%d/', blank=True, null=True ) is_superuser = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['first_name', 'last_name', 'citizenship', 'birthday', 'gender', 'passport_copy'] class Meta: verbose_name = 'Client' verbose_name_plural = 'Clients' def __str__(self): # Display model output like `John Doe (john@doe.com)` return '{} {} ({})'.format(self.first_name, self.last_name, self.email) 

The procedure is as follows:

  1. I make git clone repository (private on GitHub)
  2. I create a virtual environment python3 -m venv venv
  3. Installing dependencies pip install -r requirements.txt

Next, I start the migration with the python3 manage.py migrate command to make the initial database structure as if it were a new project. I get this error:

 Traceback (most recent call last): File ".../lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute return self.cursor.execute(sql, params) psycopg2.ProgrammingError: relation "citizenship_citizenship" does not exist LINE 1: ...enship_citizenship"."is_available_for_order" FROM "citizensh... ^ 

I understand that this error suggests that Django cannot create migrations because there is no table created for the model from the citizenship to which the model from the clients refers (like a ForeignKey ). I try to run it with the --fake and --fake-initial parameters. Does not work, the same error takes off.

Physically, I delete the clients application from the project folder and clear all references to it. And voila, the initial migration for Django was a success! Also, python3 manage.py makemigrations + subsequent migration to the database for the citizenship model passes without problems. I return the clients application back and do exactly the same actions - logically, migrations are created and migrate to the database without errors.

Tell me how to be? Is it possible to somehow hide some applications from the initial migration to an empty database? How do you do it? Share, please. After all, every time to delete applications with connections and clean up their presence throughout the code is quite time consuming.

Thank you in advance. I would be happy explanatory answers and comments.

  • I will add that the migrations that were made on localhost for clients and citizenship lie in the respective folders ( migrations ). - Vic Shóstak
  • If the base is clean. That would be enough to clear the migration in all applications. And after that, create tables. - Mr Fix

2 answers 2

You need to see the full text of the error and all migrations I suspect that the order of migration is incorrect. You must look at the migration to clients and make sure that the first migration to clients, which depends on the citizenship, has the citizenship migration, which creates the citizenship table.

    Understood, thanks to the public Python programming in Vkontakte.

    The point was this: in some strange way, when applying the initial migration, Django looks at all the files of all existing applications.

    So, in the clients/forms.py , I had a select field defined to communicate with the Citizenship model. The choices attribute was equal to Citizenship.objects.all() .

    In other words, I called objects that were not even in mine. Hence the error. As suggested in the public, this attribute can be omitted - it will pull up values ​​from the model itself. Removed, everything worked fine, but the question "why is that?" stayed.

    • Well, it's simple. When importing, this string is interpreted and Django needs to pull out all the values ​​that may not exist. - Eugene Morozov