"users_customuser" does not exist

Hey All,
I’ve run into an error that makes me believe my customuser model is not migrating.

I’m using Docker to run my Django app, PostgreSQL db, RabbitMQ broker, and Celery worker.

(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose up -d --build

The app starts fine, but when I go to login, I get an error. The output from the logs is here:

Creating string_v3_db_1 ... done
Creating string_v3_web_1 ... done
Creating string_v3_rabbitmq_1 ... done
Creating string_v3_celeryworker_1 ... done
(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose logs
Attaching to string_v3_celeryworker_1, string_v3_rabbitmq_1, string_v3_web_1, string_v3_db_1
db_1            |
db_1            | PostgreSQL Database directory appears to contain a database; Skipping initialization
db_1            |
db_1            | 2021-10-03 12:51:22.015 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db_1            | 2021-10-03 12:51:22.015 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db_1            | 2021-10-03 12:51:22.023 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db_1            | 2021-10-03 12:51:22.041 UTC [26] LOG:  database system was shut down at 2021-09-25 18:03:18 UTC
db_1            | 2021-10-03 12:51:22.058 UTC [1] LOG:  database system is ready to accept connections
db_1            | 2021-10-03 12:53:36.671 UTC [36] ERROR:  relation "users_customuser" does not exist at character 387

Abbreviating some of the logs for brevity …

_1           |   File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
web_1           |     return self.cursor.execute(sql, params)
web_1           | django.db.utils.ProgrammingError: relation "users_customuser" does not exist
web_1           | LINE 1: SELECT (1) AS "a" FROM "users_customuser" WHERE "users_custo...

Most of what I could find suggested to re-run migrations. I shut down and run migrations:

(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose down
Stopping string_v3_celeryworker_1 ... done
Stopping string_v3_rabbitmq_1     ... done
Stopping string_v3_web_1          ... done
Stopping string_v3_db_1           ... done
Removing string_v3_celeryworker_1 ... done
Removing string_v3_rabbitmq_1     ... done
Removing string_v3_web_1          ... done
Removing string_v3_db_1           ... done
Removing network string_v3_default
(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose exec web python manage.py makemigrations
(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose exec web python manage.py migrate

This doesn’t seem to solve my problem.

docker-comose.yml

version: '3.8'

services:
  web:
    build: .
    command: python /code/manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - 8000:8000
    depends_on:
      - db


  db:
    image: postgres:11
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - "POSTGRES_HOST_AUTH_METHOD=trust"


  rabbitmq:
    image: rabbitmq:3.8.18-management
    hostname: rabbitmq
    ports:
      - 15672:15672
      - 5672:5672
    expose:
      - 15672
    depends_on:
      - web


  celeryworker:
    build: .
    depends_on:
      - rabbitmq
    command: celery -A string_project worker -l info --pool=solo

volumes:
  postgres_data:

users/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

# Create your models here.

class CustomUser(AbstractUser):
	company=models.CharField(
		max_length=100, 
		null=False, # false means value is needed in db
		blank=False, #false means value is needed in forms
		editable=True,
		)

settings.py

from pathlib import Path
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'removed'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*'] #added the star here based on recommendation from Docker.  Needs to be removed for production.


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'crispy_forms',
    
    'users.apps.UsersConfig',
    'pages.apps.PagesConfig',
    'applications.apps.ApplicationsConfig'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'string_project.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'string_project.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': 5432
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/New_York'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS=(str(BASE_DIR.joinpath('static')),)
STATIC_ROOT= str(BASE_DIR.joinpath('staticfiles'))
STATFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
]
AUTH_USER_MODEL='users.CustomUser'
LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'
CRISPY_TEMPLATE_PACK = 'bootstrap4'

# Email Config
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'removed'
EMAIL_HOST_PASSWORD = 'removed'

# Celery Config
CELERY_BROKER_URL = 'amqp://rabbitmq:5672/'
#CELERY_RESULT_BACKEND = 'amqp'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_AMQP_TASK_RESULT_EXPIRES = 1000
CELERY_ACKS_LATE=False
CELERY_TASK_TRACK_STARTED=True
CELERY_SEND_TASK_EVENTS=True

I don’t have anything I’m concerned about saving in any of my databases.
Does anyone see anything that would be causing my error?

Steve

Update:

Here are updated logs related to the makemigrations and migrate:

(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose exec web python manage.py makemigrations
You are trying to change the nullable field 'company' on customuser to non-nullable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Ignore for now, and let me handle existing rows with NULL myself (e.g. because you added a RunPython or RunSQL operation to handle NULL values in a previous data migration)
 3) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> Demo
Invalid input: name 'Demo' is not defined
>>> 'Demo'
Migrations for 'users':
  users/migrations/0004_auto_20211003_1233.py
    - Alter field company on customuser
(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose exec web python manage.py migrate
Operations to perform:
  Apply all migrations: admin, applications, auth, contenttypes, sessions, users
Running migrations:
  Applying users.0004_auto_20211003_1233...Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "users_customuser" does not exist


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 85, in wrapped
    res = handle_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 243, in handle
    post_migrate_state = executor.migrate(
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 117, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 147, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 227, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/migration.py", line 124, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/operations/fields.py", line 236, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/schema.py", line 571, in alter_field
    self._alter_field(model, old_field, new_field, old_type, new_type,
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/schema.py", line 166, in _alter_field
    super()._alter_field(
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/schema.py", line 721, in _alter_field
    self.execute(
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/schema.py", line 142, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "users_customuser" does not exist

(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> docker-compose exec web python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
applications
 [X] 0001_initial
 [X] 0002_application_company
 [X] 0003_application_file
 [X] 0004_auto_20210515_2027
 [X] 0005_auto_20210515_2106
 [X] 0006_auto_20210516_1415
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0012_alter_user_first_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
pages
 (no migrations)
sessions
 [X] 0001_initial
users
 [X] 0001_initial
 [X] 0002_customuser_company
 [X] 0003_auto_20210103_1045
 [ ] 0004_auto_20211003_1233

It looks to me like the last users migration file is not completing. This is the file that was created when I selected option 1 above. Here is the migration file:

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('users', '0003_auto_20210103_1045'),
    ]

    operations = [
        migrations.AlterField(
            model_name='customuser',
            name='company',
            field=models.CharField(default='Demo', max_length=100),
            preserve_default=False,
        ),
    ]

I switched from SQLite to PostgreSQL. It almost seems like my CustomUser model did not make the transfer?

First, you probably don’t want to do a “makemigrations” in the container. When you rebuild the container, migrations are likely to end up with different names, causing problem. The migration files should be part of your source being used to create the container.

Second, having a service “depends_on” a database service is not enough to ensure that the database is actually up and running when the dependent service starts. (The “service” can be up long before the database is actually available.) If your service needing the database doesn’t have a way of handling that condition, other problems will arise. See the docs for depends_on for more information.

Thanks Ken.

With the comment about depends_on, do you think I have a db startup error where PostgreSQL isn’t starting? I see now in the documents this line:

  • depends_on does not wait for db and redis to be “ready” before starting web - only until they have been started. If you need to wait for a service to be ready, see Controlling startup order for more on this problem and strategies for solving it.

If PostgreSQL started, but never got up and ‘ready’, should I see that in the logs?

I was following Will Vincent’s Django for Professionals on the makemigrations, but I’ll try to remake migrations outside of it.

Given where I’m at, would you suggest I just delete the current migration files and start over?

Steve

That seems to be the safest path from what I can see. (To be explicitly clear - actually running the migrations in the container is fine. It’s running makemigrations that can cause problems.)

In general, yes - I would expect to see your app throwing a connection error if that’s what’s happening. (It might not show up in your docker logs if you’re using the python logging module and logging errors elsewhere. But I would expect them to be logged somewhere.)

This part of the log leads me to believe that there are existing entries in the CustomUser db. If I just delete the migration files, does it also clear the db, or do I need to do that somewhere as well?

Yes, I would suggest dropping and recreating the database. That’s something done completely outside of Django.

Here’s what I did:

  • Deleted all migrations in the folder except for __init__.py
  • Deleted all files in the migrations __pycache__ folder except for __init__.cpython-38.pyc

I did this for all models that had migrations.
I then tried to make migrations:
(string_v3) PS C:\Users\steve\Desktop\Coding\string_v3> python manage.py makemigrations

This is the output I got:

Traceback (most recent call last):
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 219, in ensure_connection
    self.connect()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\postgresql\base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\psycopg2\__init__.py", line 127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "db" to address: Unknown host


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\base.py", line 330, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\base.py", line 371, in execute
    output = self.handle(*args, **options)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\base.py", line 85, in wrapped
    res = handle_func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\core\management\commands\makemigrations.py", line 101, in handle
    loader.check_consistent_history(connection)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\migrations\loader.py", line 290, in check_consistent_history
    applied = recorder.applied_migrations()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\migrations\recorder.py", line 77, in applied_migrations
    if self.has_table():
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\migrations\recorder.py", line 55, in has_table
    with self.connection.cursor() as cursor:
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 259, in cursor
    return self._cursor()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 235, in _cursor
    self.ensure_connection()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 219, in ensure_connection
    self.connect()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 219, in ensure_connection
    self.connect()
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\base\base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\utils\asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\django\db\backends\postgresql\base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "C:\Users\steve\Desktop\Coding\string_v3\lib\site-packages\psycopg2\__init__.py", line 127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not translate host name "db" to address: Unknown host

I"m not sure if the error above is related to my previous errors, but it seems like it could be. I’d be interested in any input; in the meantime, I’ll be reading docs and googling. :slight_smile:

Steve

Pretty straight forward.

Whatever you’re running this on doesn’t recognize db as a valid host name. As this is not a valid DNS entry, you would need to have this defined somewhere for local name resolution.

Your settings file looks like it’s set up to work within the docker environment, but you’re trying to run makemigrations from the command line.

So I ended up getting things back on track. I can’t say for sure what the root cause was, but in case anyone comes across this looking for a solution, here are the additional steps I took:

  • In settings.py, I switched back to sqlite db to run makemigrations, and that worked fine.
  • In settings.py, I switched back to postgreSQL, started my docker containers, then ran the migrate, and it worked fine.

The CustomUser model also migrated fine. A few pages I checked are working and all of my tests passed. My take away is that my root cause is likely related to Ken’s suggestion:

Steve