Search code examples
pythonmysqldjangomigrationdjango-database

Changed DB engine to MySQL. Now Django does not create tables


I have a Django app with a standard sqlite3 DB. Now I want to use MySQL. So I changed my DATABASES in settings.py, and it works well, but I can't run server because it says

django.db.utils.InternalError: (1049, "Unknown database 'django'")

So I created this DB in the client, and now it says

django.db.utils.ProgrammingError: (1146, "Table 'django.Cat' doesn't exist")

Seems like I have to create all tables by myself, which is the worst variant I can do.

#settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '/path/to/db.conf',
        },
    }
}

and

#conf.db
[client]
database = django
host = localhost
user = DjangoUser
password = password_you_cant_guess
default-character-set = utf8

How to make Django create all tables I have?

I even can't run python3 manage.py with any command because it gives my this exception.

Traceback:

Traceback (most recent call last):
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 74, in execute
    return self.cursor.execute(query, args)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 209, in execute
    res = self._query(query)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 315, in _query
    db.query(q)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 239, in query
    _mysql.connection.query(self, query)
MySQLdb._exceptions.ProgrammingError: (1146, "Table 'django.Cat' doesn't exist")

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

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/path/to/project/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 377, in execute
    django.setup()
  File "/path/to/project/venv/lib/python3.6/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/apps/registry.py", line 122, in populate
    app_config.ready()
  File "/path/to/project/External/apps.py", line 13, in ready
    active_cats = list(Cat.objects.filter(active_cat=True).all())
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/models/query.py", line 276, in __iter__
    self._fetch_all()
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1261, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/models/query.py", line 57, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1151, in execute_sql
    cursor.execute(sql, params)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 100, in execute
    return super().execute(sql, params)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 86, in _execute
    return self.cursor.execute(sql, params)
  File "/path/to/project/venv/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 74, in execute
    return self.cursor.execute(query, args)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 209, in execute
    res = self._query(query)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/cursors.py", line 315, in _query
    db.query(q)
  File "/path/to/project/venv/lib/python3.6/site-packages/MySQLdb/connections.py", line 239, in query
    _mysql.connection.query(self, query)
django.db.utils.ProgrammingError: (1146, "Table 'django.Cat' doesn't exist")

Solution

  • Your issue is here:

    File "/path/to/project/External/apps.py", line 13, in ready
        active_cats = list(Cat.objects.filter(active_cat=True).all())
    

    This code is executed as part of the initialization process. This is what prevents you from executing any management command. Note that this is documented with a very clear warning:

    Warning

    Although you can access model classes as described above, avoid interacting with the database in your ready() implementation. This includes model methods that execute queries (save(), delete(), manager methods etc.), and also raw SQL queries via django.db.connection. Your ready() method will run during startup of every management command. For example, even though the test database configuration is separate from the production settings, manage.py test would still execute some queries against your production database!