Creating web applications using the Django framework is very convenient. If you compare the MVC model, it implements complicated details in the Model and View parts, helping the programmer to focus on what he wants to do (Control). This time, I would like to describe migrations related to the Model part. Refer to Django Official Tutorial for Django's Project creation settings, and [here](https://docs. djangoproject.com/en/1.11/topics/migrations/#historical-models) is referenced.
Translated into Japanese, migrations means "migration." In Django, it's primarily about the ability to automatically change user-designed data structures into a database schema (you can write a migrations file manually, but I'll show you more if I get the chance).
Let's create an app by referring to Tutorial (however, only the data model part).
Development environment |
---|
Mac OS:Sierra |
python2.7.10 |
django1.11.2 |
mysql5.7.18 |
Enter the working directory and enter the following command in the terminal:
django-admin startproject m_Migration
python manage.py startapp polls
You have now created a polls app in the project m_Migration and inside. Next, set up the database. It uses mysql instead of the default sqlite, so You need to modify the project settings file.
python:settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'blog',
'USER':'user',
'PASSWORD':'',
'HOST':'',
'PORT':'3306',
}
}
After that, reflect the initial settings in the terminal.
python manage.py migrate
log:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
If you go into the mysql client and look at the tables you currently have in the database blog:
+----------------------------+
| Tables_in_blog |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
A framework-related database has been created. Currently only polls apps have a model.py module, so the polls package created a migrations folder.
Create a data model Category and Article for use in the polls app.
models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
text = models.CharField(max_length=1000)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
The function of the polls app is to display saved blog posts. Therefore, we created an article model Article and a Category model that shows the genre of the article. In order to reflect the created model, first create a migrations file that describes the operation.
python manage.py makemigrations polls
log:
Migrations for 'polls':
polls/migrations/0001_initial.py
- Create model Article
- Create model Category
- Add field category to article
Here, in the migrations / folder, I created a migrations file 0001_initial.py that records the changes to model.py this time. Next, reflect the created migrations file
python manage.py migrate
log:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
Now in the database
+----------------------------+
| Tables_in_blog |
+----------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
| polls_article |
| polls_category |
+----------------------------+
Looking at the table schema:
mysql>DESC polls_article;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(100) | NO | | NULL | |
| text | varchar(1000) | NO | | NULL | |
| category_id | int(11) | NO | MUL | NULL | |
+-------------+---------------+------+-----+---------+----------------+
mysql>DESC polls_category;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
A new polls app table (polls_article, polls_category) has been created according to the model (id field is automatically created by default). So far, the flow of designing a model with an app and creating a database using django's migrations function.
We may create it once and then modify the data model, such as adding new features.
Take the polls app as an example. For example, the original blog service provided articles with only text, but since I bought a good digital camera, the up owner wants to add a photo to the article. Now let's add a field image_url to the Article model to store the photo url (also set the default value for existing records).
models.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
text = models.CharField(max_length=1000)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
image_url = models.URLField(max_length=200, default='toBeImplement')
Record your changes
python manage.py makemigrations polls
log:
Migrations for 'polls':
polls/migrations/0002_article_image_url.py
- Add field image_url to article
A new migrations file 0002_article_image_url.py has been created.
Reflect the changes.
python manage.py migrate
Database Let's take a look at the current schema:
DESC polls_article;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(100) | NO | | NULL | |
| text | varchar(1000) | NO | | NULL | |
| category_id | int(11) | NO | MUL | NULL | |
| image_url | varchar(200) | NO | | NULL | |
+-------------+---------------+------+-----+---------+----------------+
I was able to update the database as planned.
You can also control the version of the data model, like VCS such as git. One of the highlights of this feature is the recovery of data models in emergencies. Assuming that I made the changes related to the photo url in the above example, I ran the migrate command with the migrations file 0002_article_image_url.py created.
python manage.py migrate
Here migrate failed. The latest migrations state is 0002_article_image_url.py, but the actual database schema corresponds to 0001_initial.py. In this state, there is no column corresponding to the photo url in the table. I get an error when I try to access the photo url data from the polls app. One workaround for this issue is to restore the state of migrations to 0001_initial.py (and then look for the bag).
To recover, also use the migrate command to recover to the state recorded in the migrations file 0001_initial.py.
python manage.py migrate polls 0001_initial
log:
Operations to perform:
Target specific migration: 0001_initial, from polls
Running migrations:
Rendering model states... DONE
Unapplying polls.0002_article_image_url... OK
As the log shows, the changes in 0002_article_image_url.py have been unapplyed. Let's take a look at the current Article table schema:
DESC polls_article;
+-------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(100) | NO | | NULL | |
| text | varchar(1000) | NO | | NULL | |
| category_id | int(11) | NO | MUL | NULL | |
+-------------+---------------+------+-----+---------+----------------+
The table has returned to its original state.
Recommended Posts