Using Django 2.1 with MySQL 8
A framework can be a great way to allow you to spend more time on the actual application or web site and less time on standard tasks. It can also greatly reduce the amount of custom code needed. Django is one of the best known web frameworks for Python, and the good news is that it works out of the box with MySQL Server 8 and MySQL Connector/Python 8. This blog will look at how to use Django with MySQL 8.
There actually is very little to get Django to work with MySQL 8. Just install it, configure Django to use MySQL Connector/Python as a backend, and that's it. From the Django point of view, you just have to configure the database option in settings.py
to use MySQL Connector/Python and your database settings, for example:
DATABASES = {
'default': {
'NAME': 'mydb',
'ENGINE': 'mysql.connector.django',
'USER': 'django',
'PASSWORD': '$@jkHhj34N!bd',
'OPTIONS': {
'autocommit': True,
},
}
}
Obviously this assumes, you have MySQL installed already. If you do not, the rest of the blog includes a more comprehensive list of steps. The first step is to install MySQL Server.
Installing MySQL Server
There are several ways to install MySQL Server and which one is the best depends on your circumstances and preferences. For the sake of this blog, I will show how MySQL Server can be installed on Oracle Linux/RHEL/CentOS 7 using RPMs and on Microsoft Windows using MySQL Installer. For more options, see the installation chapter in the reference manual. Let's look at the Linux installation first.
RPM Install on Enterprise Linux
MySQL provides repositories for several Linux distributions including the Oracle Linux/RHEL/CentOS family. This makes it easy to install MySQL. The step to install the repository definition is:
shell$ sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpmLoaded plugins: langpacks, ulninfo
Repository ol7_developer_EPEL is listed more than once in the configuration
mysql80-community-release-el7-1.noarch.rpm | 25 kB 00:00:00
Examining /var/tmp/yum-root-Ts4OzC/mysql80-community-release-el7-1.noarch.rpm: mysql80-community-release-el7-1.noarch
Marking /var/tmp/yum-root-Ts4OzC/mysql80-community-release-el7-1.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package mysql80-community-release.noarch 0:el7-1 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
======================================================================================================
Package Arch Version Repository Size
======================================================================================================
Installing:
mysql80-community-release noarch el7-1 /mysql80-community-release-el7-1.noarch 31 k
Transaction Summary
======================================================================================================
Install 1 Package
Total size: 31 k
Installed size: 31 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : mysql80-community-release-el7-1.noarch 1/1
Verifying : mysql80-community-release-el7-1.noarch 1/1
Installed:
mysql80-community-release.noarch 0:el7-1
Complete!
Now, you can install MySQL Server. There are several RPMs to choose from and which you need depends on which other features you need to use. A common set of RPMs can be installed as:
shell$ sudo yum install mysql-community-server mysql-community-libs
mysql-community-libs-compat mysql-community-common mysql-community-client
...
On the first start, the data directory will be initialized:
shell$ sudo systemctl start mysqld
To keep a fresh installation secure, a random password has been set for the root user. This can be found from the MySQL error log:
shell$ sudo grep password /var/log/mysqld.log
2018-11-05T08:05:09.985857Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: KWNfuA!1r:PF
Use this password to connect to MySQL and update the password (please use a strong password):
shell$ mysql --user=root --password
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 19
Server version: 8.0.13 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> ALTER USER root@localhost IDENTIFIED BY 'Kij0@jDi~Faf4';
Query OK, 0 rows affected (0.13 sec)
MySQL is now ready for use. Before continuing, I will show an example of installing MySQL on Microsoft Windows.
Microsoft Windows
On Microsoft Windows an easy way to install MySQL is to use the MySQL Installer. The installer can be downloaded from the MySQL download site. The MySQL Installer can be used to install most MySQL products. If you start MySQL Installer for the first time, you will be taken directly to the screen to choose the products to install; if you already have installed products, you will need to choose to add new products.
On the Select Products and Features screen, choose to install MySQL Server 8.0 (MySQL Installer will list the latest release from the list of available products):
Optionally, you can filter the list of products. Feel free to choose other products you want. MySQL Notifier can be useful for starting and stopping MySQL, if you do not plan to have MySQL running at all times. You can also install MySQL Connector/Python this way, however for this blog a different method will be used.
Follow the installation wizard. For this blog, the default choices will work, though during the configuration you may want to ensure Open Windows Firewall ports for network access is unchecked unless you need remote access.
Before you can connect to MySQL from your Django program, you need a user and a schema (database) to use from your web site.
Preparing MySQL Server
While MySQL is now ready to work with Django, you will likely want to do a few more preparation steps. Here creating the MySQL user and schema (database) used by Django and support for named time zones will be covered.
Creating the User and Schema
An example of creating the user django@localhost
and give it all privileges to the mydb
schema and to create the mydb
schema is:
mysql> CREATE USER django@localhost IDENTIFIED BY '$@jkHhj34N!bd';
Query OK, 0 rows affected (0.11 sec)
mysql> GRANT ALL ON mydb.* TO django@localhost;
Query OK, 0 rows affected (0.11 sec)
mysql> CREATE DATABASE mydb CHARACTER SET utf8mb4;
Query OK, 1 row affected (0.07 sec)
This will allow the django
user to connect from the same host as MySQL Server is installed by authenticating with the password $@jkHhj34N!bd
.
In MySQL 8 it is not necessary to specify the database character set to utf8mb4
as it is the default. However, if you use an older version of MySQL Server, you should ensure you are using UTF-8. The utf8mb4
character set means that characters using up to four bytes are supported.
Named Time Zones
If you want to used named time zones (for example Australia/Sydney), you will need to install the data for these in MySQL. On Linux you can use the mysql_tzinfo_to_sql
script that comes with the MySQL installation:
shell$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql --user=root --password mysql
On Microsoft Windows, you need to download the time zone information and load these into the database, for example:
mysql> use mysql
Database changed
mysql> SOURCE timezone_posix.sql
See also MySQL Server Time Zone Support in the reference manual.
Now, you can move on to MySQL Connector/Python and Django.
Installing MySQL Connector/Python and Django
Both MySQL Connector/Python and Django can be installed in a platform independent way using the pip
command. Since Django 2.1 is only available for Python 3.4 and later, it is recommended to use Python 3.4 or later. This blog assumes Python 3.6. (MySQL Connector/Python 8.0.13 and later also supports Python 3.7.)
If you do not have Python 3.6 installed on Oracle Linux/RHEL/CentOS 7, you can easily install it for example from for EPEL repository. Assuming you have configured the EPEL repository, the following steps install Python 3.6, enable pip
, and update pip
to the latest version:
shell$ yum install python36
shell$ python3.6 -m ensurepip
shell$ python3.6 -m pip install --upgrade pip
You can now use python3.6
to invoke Python 3.6. In the following, replace python
with python3.6
if you have installed Python 3.6 in this way.
To install the latest MySQL Connector/Python release (currently 8.0.13):
PS:> python -m pip install mysql-connector-python
Collecting mysql-connector-python
Downloading https://files.pythonhosted.org/packages/4a/91/ffdd28ae0f8e01b09df67a4e48cef17a1a5374cd0ce0f2fe27e1d635423e/mysql_connector_python-8.0.13-cp36-cp36m-wi
(3.2MB)
100% |████████████████████████████████| 3.2MB 3.0MB/s
Requirement already satisfied: protobuf>=3.0.0 in c:usersmyuserappdatalocalprogramspythonpython36libsite-packages (from mysql-connector-pytho
st1)
Requirement already satisfied: six>=1.9 in c:usersmyuserappdatalocalprogramspythonpython36libsite-packages (from protobuf>=3.0.0->mysql-conne
(1.11.0)
Requirement already satisfied: setuptools in c:usersmyuserappdatalocalprogramspythonpython36libsite-packages (from protobuf>=3.0.0->mysql-con
n) (28.8.0)
Installing collected packages: mysql-connector-python
Successfully installed mysql-connector-python-8.0.13
Similar for installing Django:
PS:> python -m pip install Django
Collecting Django
Downloading https://files.pythonhosted.org/packages/d1/e5/2676be45ea49cfd09a663f289376b3888accd57ff06c953297bfdee1fb08/Django-2.1.3-py3-none-any.whl (7.3MB)
100% |████████████████████████████████| 7.3MB 1.8MB/s
Collecting pytz (from Django)
Downloading https://files.pythonhosted.org/packages/f8/0e/2365ddc010afb3d79147f1dd544e5ee24bf4ece58ab99b16fbb465ce6dc0/pytz-2018.7-py2.py3-none-any.whl (506kB)
100% |████████████████████████████████| 512kB 10.5MB/s
Installing collected packages: pytz, Django
Successfully installed Django-2.1.3 pytz-2018.7
That's it. Now you are ready to use Django with MySQL Connector/Python 8 and MySQL Server 8.
Using Django
I will not go into details of how to use Django. If you are new to Django, you can consider going through the tutorial for Django 2.1 on the Django website. This sets up a web site using a database backend. The important thing with respect to MySQL is the configuration of the DATABASE
property in settings.py
(the first step in part 2):
DATABASES = {
'default': {
'NAME': 'mydb',
'ENGINE': 'mysql.connector.django',
'USER': 'django',
'PASSWORD': '$@jkHhj34N!bd',
'OPTIONS': {
'autocommit': True,
'use_pure': True,
},
}
}
The key here is the engine. You need to set it to mysql.connector.django
to use MySQL Connector/Python. The rest of the options are schema name, credentials, and MySQL Connector/Python specific options. The use_pure
option is set to True
due to the problem reported in Django bug 30469 and MySQL bug 92001 (thanks to Dmytro Gierman for letting me know about that).
The Django documentation also has more information about using MySQL as the database. A couple of updates of the statements in the document:
- As of MySQL 8, InnoDB does correctly restore the auto-increment ID after a restart.
- The default character set in MySQL 8 is UTF-8 (called
utf8mb4
in MySQL). - There is also support for a C Extension in MySQL Connector/Python. In MySQL 8 this is the default for the platforms/Python version where the C Extension is installed.
The rest is all Python and Django. Have fun creating your next web site with Django, MySQL Connector/Python 8, and MySQL 8.
If you are interested in learning more about MySQL Connector/Python 8, then I am the author of MySQL Connector/Python Revealed (Apress) – also available at Amazon and other bookshops.
django.core.exceptions.ImproperlyConfigured: ‘mysql.connector.django’ isn’t an available database backend.
Try using ‘django.db.backends.XXX’, where XXX is one of:
‘mysql’, ‘oracle’, ‘postgresql’, ‘sqlite3’
Are you using Django 3.0? The blog is about Django 2.1, so the instructions won’t work for 3.0.
mysql-connector-python, starting from version 8.0.13, has a bug, which makes it impossible to use with Django.
To avoid the bug, add option
‘use_pure’: True
in database options.
https://code.djangoproject.com/ticket/30469#comment:5
https://bugs.mysql.com/bug.php?id=92001
I’m using version 8.0.21 and it doesn’t work
What is the error? And which version of Django are you using? Last I checked, Django for some reason explicitly does not allow MySQL Connector/Python for version 3.0.