django迁移
Since version 1.7, Django has come with built-in support for database migrations. In Django, database migrations usually go hand in hand with models: whenever you code up a new model, you also generate a migration to create the necessary table in the database. However, migrations can do much more.
从1.7版开始,Django内置了对数据库迁移的支持。 在Django中,数据库迁移通常与模型并驾齐驱:每当编写新模型时,您都会生成一个迁移以在数据库中创建必要的表。 但是,迁移可以做的更多。
You are going to learn how Django Migrations work and how you can get the most out of them over the course of four articles and one video:
您将通过四篇文章和一部视频学习Django迁移的工作原理,以及如何从中获得最大收益:
- Part 1: Django Migrations: A Primer (current article)
- Part 2: Digging Deeper into Migrations
- Part 3: Data Migrations
- Video: Django 1.7 Migrations – primer
- 第1部分:Django迁移:入门(当前文章)
- 第2部分: 深入研究迁移
- 第3部分: 数据迁移
- 视频: Django 1.7迁移-入门
In this article, you’ll get comfortable with Django migrations and learn the following:
在本文中,您将熟悉Django迁移并学习以下内容:
- How to create database tables without writing any SQL
- How to automatically modify your database after you changed your models
- How to revert changes made to your database
- 如何在不编写任何SQL的情况下创建数据库表
- 更改模型后如何自动修改数据库
- 如何还原对数据库所做的更改
Free Bonus: Click here to get access to a free Django Learning Resources Guide (PDF) that shows you tips and tricks as well as common pitfalls to avoid when building Python + Django web applications.
免费红利: 单击此处可获得免费的Django学习资源指南(PDF) ,其中显示了一些技巧和窍门,以及在构建Python + Django Web应用程序时应避免的常见陷阱。
迁移解决的问题 (The Problems That Migrations Solve)
If you are new to Django or web development in general, you might not be familiar with the concept of database migrations, and it might not seem obvious why they’re a good idea.
如果您一般不熟悉Django或Web开发,那么您可能不熟悉数据库迁移的概念,并且似乎不太清楚为什么它们是一个好主意。
First, let’s quickly define a couple of terms to make sure everybody is on the same page. Django is designed to work with a relational database, stored in a relational database management system like PostgreSQL, MySQL, or SQLite.
首先,让我们快速定义几个术语以确保每个人都在同一页面上。 Django设计用于处理关系数据库 ,该关系数据库存储在关系数据库管理系统(如PostgreSQL , MySQL或SQLite)中 。
In a relational database, data is organized in tables. A database table has a certain number of columns, but it can have any number of rows. Each column has a specific datatype, like a string of a certain maximum length or a positive integer. The description of all tables with their columns and their respective datatypes is called a database schema.
在关系数据库中,数据以表的形式组织。 数据库表具有一定数量的列,但是它可以具有任意数量的行。 每列都有特定的数据类型,例如最大长度一定的字符串或正整数。 所有表及其列和各自的数据类型的描述称为数据库模式。
All database systems supported by Django use the language SQL to create, read, update and delete data in a relational database. SQL is also used to create, change, and delete the database tables themselves.
Django支持的所有数据库系统都使用SQL语言在关系数据库中创建,读取,更新和删除数据。 SQL还用于创建,更改和删除数据库表本身。
Working directly with SQL can be quite cumbersome, so to make your life easier, Django comes with an object-relational mapper, or ORM for short. The ORM maps the relational database to the world of object oriented programming. Instead of defining database tables in SQL, you write Django models in Python. Your models define database fields, which correspond to the columns in their database tables.
直接使用SQL可能会很麻烦,因此为了使您的生活更轻松,Django附带了一个对象关系映射器,简称ORM。 ORM将关系数据库映射到面向对象编程的世界。 不用用SQL定义数据库表,而是用Python编写Django模型 。 您的模型定义数据库字段,这些字段对应于其数据库表中的列。
Here’s an example of how a Django model class is mapped to a database table:
这是一个如何将Django模型类映射到数据库表的示例:
But just defining a model class in a Python file does not make a database table magically appear out of nowhere. Creating the database tables to store your Django models is the job of a database migration. Additionally, whenever you make a change to your models, like adding a field, the database has to be changed too. Migrations handle that as well.
但是,仅在Python文件中定义模型类并不能使数据库表神奇地出现。 创建数据库表来存储Django模型是数据库迁移的工作。 此外,每当您对模型进行更改(例如添加字段)时,也必须更改数据库。 迁移也可以解决这一问题。
Here are a few ways Django migrations make your life easier.
以下是Django迁移使您的生活更轻松的几种方法。
不使用SQL进行数据库更改 (Making Database Changes Without SQL)
Without migrations, you would have to connect to your database and type in a bunch of SQL commands or use a graphical tool like PHPMyAdmin to modify the database schema every time you wanted to change your model definition.
如果不进行迁移,则每次想更改模型定义时,都必须连接到数据库并键入一堆SQL命令或使用诸如PHPMyAdmin之类的图形工具来修改数据库架构。
In Django, migrations are primarily written in Python, so you don’t have to know any SQL unless you have really advanced use cases.
在Django中,迁移主要是用Python编写的,因此,除非您拥有真正的高级用例,否则您无需了解任何SQL。
避免重复 (Avoiding Repetition)
Creating a model and then writing SQL to create the database tables for it would be repetitive.
创建一个模型,然后编写SQL为其创建数据库表将是重复性的。
Migrations are generated from your models, making sure you don’t repeat yourself.
迁移是根据您的模型生成的,请确保您不会重复自己 。
确保模型定义和数据库架构同步 (Ensuring Model Definitions and the Database Schema in Sync)
Usually, you have multiple instances of your database, for example one database for each developer in your team, a database for testing and a database with live data.
通常,您有数据库的多个实例,例如团队中每个开发人员的一个数据库,一个用于测试的数据库和一个包含实时数据的数据库。
Without migrations, you will have to perform any schema changes on each one of your database, and you will have to keep track which changes have already been made to which database.
如果不进行迁移,则必须在数据库的每个数据库上执行任何架构更改,并且必须跟踪已对哪个数据库进行了哪些更改。
With Django Migrations, you can easily keep multiple databases in sync with your models.
使用Django迁移,您可以轻松地使多个数据库与模型保持同步。
跟踪版本控制中的数据库架构更改 (Tracking Database Schema Change in Version Control)
A version control system, like Git is excellent for code, but not so much for database schemas.
像Git这样的版本控制系统非常适合代码,但对于数据库模式则不是那么好。
As migrations are plain Python in Django, you can put them in a version control system just like any other piece of code.
由于迁移是Django中的普通Python,因此您可以像其他任何代码一样将其放入版本控制系统中。
By now, you’re hopefully convinced that migrations are a useful and powerful tool. Let’s start learning how to unleash that power.
到目前为止,您已经确信迁移是一种有用且功能强大的工具。 让我们开始学习如何释放这种力量。
设置Django项目 (Setting Up a Django Project)
Throughout this tutorial, you are going to work on a simple Bitcoin tracker app as an example project.
在本教程中,您将以一个简单的比特币跟踪器应用程序作为示例项目。
The first step is to install Django. Here is how you do that on Linux or macOS X using a virtual environment:
第一步是安装Django。 这是您使用虚拟环境在Linux或macOS X上执行的操作:
$ python3 -m venv env
$ python3 -m venv env
$ $ source env/bin/activate
source env/bin/activate
(env) $ $ pip install (env) $ $ pip install "Django==2.1.*"
"Django==2.1.*"
...
...
Successfully installed Django-2.1.3
Successfully installed Django-2.1.3
Now you have created a new virtual environment and activated it, as well as installed Django in that virtual environment.
现在,您已经创建并激活了一个新的虚拟环境,并在该虚拟环境中安装了Django。
Note that on Windows, you would run env/bin/activate.bat
instead of source env/bin/activate
to activate your virtual environment.
请注意,在Windows上,您将运行env/bin/activate.bat
而不是source env/bin/activate
来激活虚拟环境。
For easier readability, console examples won’t include the (env)
part of the prompt from now on.
为了更容易阅读,控制台示例从现在开始将不包含提示的(env)
部分。
With Django installed, you can create the project using the following commands:
安装Django后,您可以使用以下命令创建项目:
This gives you a simple project and an app called historical_data
. You should now have this directory structure:
这为您提供了一个简单的项目和一个名为historical_data
的应用程序。 您现在应该具有以下目录结构:
bitcoin_tracker/
|
├── bitcoin_tracker/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
|
├── historical_data/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations/
│ │ └── __init__.py
| |
│ ├── models.py
│ ├── tests.py
│ └── views.py
|
└── manage.py
bitcoin_tracker/
|
├── bitcoin_tracker/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
|
├── historical_data/
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations/
│ │ └── __init__.py
| |
│ ├── models.py
│ ├── tests.py
│ └── views.py
|
└── manage.py
Within the bitcoin_tracker
directory, there are two sub-directories: bitcoin_tracker
for project-wide files and historical_data
containing files for the app you created.
内bitcoin_tracker
目录中,有两个子目录: bitcoin_tracker
项目范围内的文件和historical_data
包含文件为您创建的应用程序。
Now, to create a model, add this class in historical_data/models.py
:
现在,要创建模型,请在historical_data/models.py
添加此类:
This is the basic model to keep track of Bitcoin prices.
这是跟踪比特币价格的基本模型。
Also, don’t forget to add the newly created app to settings.INSTALLED_APPS
. Open bitcoin_tracker/settings.py
and append historical_data
to the list INSTALLED_APPS
, like this:
另外,不要忘记将新创建的应用添加到settings.INSTALLED_APPS
。 打开bitcoin_tracker/settings.py
并追加historical_data
到列表INSTALLED_APPS
,就像这样:
INSTALLED_APPS INSTALLED_APPS = = [
[
'django.contrib.admin''django.contrib.admin' ,
,
'django.contrib.auth''django.contrib.auth' ,
,
'django.contrib.contenttypes''django.contrib.contenttypes' ,
,
'django.contrib.sessions''django.contrib.sessions' ,
,
'django.contrib.messages''django.contrib.messages' ,
,
'django.contrib.staticfiles''django.contrib.staticfiles' ,
,
'historical_data''historical_data' ,
,
]
]
The other settings are fine for this project. This tutorial assumes that your project is configured to use an SQLite database, which is the default.
其他设置适用于该项目。 本教程假定您的项目已配置为使用SQLite数据库,这是默认数据库。
创建迁移 (Creating Migrations)
With the model created, the first thing you need to do is create a migration for it. You can do this with the following command:
创建模型后,您要做的第一件事就是为其创建迁移。 您可以使用以下命令执行此操作:
Note: Specifying the name of the application, historical_data
, is optional. Leaving it off creates migrations for all apps.
注:指定应用程序的名称, historical_data
,是可选的。 保留它会为所有应用程序创建迁移。
This creates the migrations file that instructs Django on how to create the database tables for the models defined in your application. Let’s have another look at the directory tree:
这将创建迁移文件,该文件指导Django如何为应用程序中定义的模型创建数据库表。 让我们再来看一下目录树:
bitcoin_tracker/
|
├── bitcoin_tracker/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
|
├── historical_data/
│ ├── migrations/
bitcoin_tracker/
|
├── bitcoin_tracker/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
|
├── historical_data/
│ ├── migrations/
│ │ ├── 0001_initial.py
│ │ └── __init__.py
| |
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
|
├── db.sqlite3
└── manage.py
│ │ ├── 0001_initial.py
│ │ └── __init__.py
| |
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
|
├── db.sqlite3
└── manage.py
As you can see, the migrations
directory now contains a new file: 0001_initial.py
.
如您所见, migrations
目录现在包含一个新文件: 0001_initial.py
。
Note: You might notice that running the makemigrations
command also created the file db.sqlite3
, which contains your SQLite database.
注意:您可能会注意到,运行makemigrations
命令还创建了文件db.sqlite3
,该文件包含您SQLite数据库。
When you try to access a non-existing SQLite3 database file, it will automatically be created.
当您尝试访问不存在SQLite3数据库文件时,将自动创建该文件。
This behavior is unique to SQLite3. If you use any other database backend like PostgreSQL or MySQL, you have to create the database yourself before running makemigrations
.
此行为是SQLite3独有的。 如果使用其他任何数据库后端(如PostgreSQL或MySQL),则必须在运行makemigrations
之前自己创建数据库。
You can take a peek at the database with the dbshell
management command. In SQLite, the command to list all tables is simply .tables
:
您可以使用dbshell
management命令查看数据库。 在SQLite中,列出所有表的命令只是.tables
:
The database is still empty. That will change when you apply the migration. Type .quit
to exit the SQLite shell.
数据库仍然为空。 当您应用迁移时,情况将会改变。 键入.quit
退出SQLite Shell。
应用迁移 (Applying Migrations)
You have now created the migration, but to actually make any changes in the database, you have to apply it with the management command migrate
:
现在已经创建了迁移,但实际上使数据库中的任何变化,你必须与管理命令应用它migrate
:
$ python manage.py migrate
$ python manage.py migrate
Operations to perform:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Running migrations:
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying historical_data.0001_initial... OK
Applying historical_data.0001_initial... OK
Applying sessions.0001_initial... OK
Applying sessions.0001_initial... OK
There is a lot going on here! According to the output, your migration has been successfully applied. But where do all the other migrations come from?
这里有很多事情! 根据输出,您的迁移已成功应用。 但是其他所有迁移都从何而来?
Remember the setting INSTALLED_APPS
? Some of the other apps listed there also come with migrations, and the migrate
management command applies the migrations for all installed apps by default.
还记得设置INSTALLED_APPS
吗? 有些所列的其他应用还配备了迁移,并且migrate
管理命令应用迁移在默认情况下所有安装的应用程序。
Have another look at the database:
再看一下数据库:
Now there are multiple tables. Their names give you an idea of their purpose. The migration that you generated in the previous step has created the historical_data_pricehistory
table. Let’s inspect it using the .schema
command:
现在有多个表。 他们的名字使您对他们的目的有所了解。 您在上一步中生成的迁移已创建了historical_data_pricehistory
表。 让我们使用.schema
命令检查它:
sqlite> .schema --indent historical_data_pricehistory
sqlite> .schema --indent historical_data_pricehistory
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory"(
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory"(
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date" datetime NOT NULL,
"date" datetime NOT NULL,
"price" decimal NOT NULL,
"price" decimal NOT NULL,
"volume" integer unsigned NOT NULL
"volume" integer unsigned NOT NULL
);
);
The .schema
command prints out the CREATE
statement that you would execute to create the table. The parameter --indent
formats it nicely. Even if you are not familiar with SQL syntax, you can see that the schema of the historical_data_pricehistory
table reflects the fields of the PriceHistory
model.
.schema
命令将打印出您要执行以创建表的CREATE
语句。 参数--indent
可以很好地格式化它。 即使你不熟悉SQL语法,你可以看到的架构historical_data_pricehistory
表反映的领域PriceHistory
模型。
There is a column for each field and an additional column id
for the primary key, which Django creates automatically unless you explicitly specify a primary key in your model.
除非您在模型中明确指定主键,否则Django将自动为每个字段提供一列,并为主键附加一个列id
。
Here’s what happens if you run the migrate
command again:
如果再次运行migrate
命令,将会发生以下情况:
Nothing! Django remembers which migrations have already been applied and does not try to rerun them.
没有! Django会记住已经应用了哪些迁移,因此不会尝试重新运行它们。
It is worth noting that you can also limit the migrate
management command to a single app:
值得注意的是,您还可以将migrate
管理命令限制为单个应用程序:
$ python manage.py migrate historical_data
$ python manage.py migrate historical_data
Operations to perform:
Operations to perform:
Apply all migrations: historical_data
Apply all migrations: historical_data
Running migrations:
Running migrations:
No migrations to apply.
No migrations to apply.
As you can see, Django now only applies migrations for the historical_data
app.
正如你可以看到,现在的Django只为应用迁移historical_data
应用。
When you are running the migrations for the first time, it is a good idea to apply all migrations to ensure your database contains the necessary tables for the features you might take for granted, like user authentication and sessions.
首次运行迁移时,最好应用所有迁移,以确保数据库包含必要的表,这些表是您理所当然的功能(例如用户身份验证和会话)。
改变模型 (Changing Models)
Your models are not set in stone. Your models will change as your Django project gains more features. You might add or remove fields or change their types and options.
您的模型并非一成不变。 随着Django项目获得更多功能,您的模型将发生变化。 您可以添加或删除字段或更改其类型和选项。
When you change the definition of a model, the database tables used to store these models have to be changed too. If your model definitions don’t match your current database schema, you will most likely run into a django.db.utils.OperationalError
.
更改模型的定义时,也必须更改用于存储这些模型的数据库表。 如果您的模型定义与当前数据库模式不匹配,则很可能会遇到django.db.utils.OperationalError
。
So how do you change the database tables? By creating and applying a migration.
那么,如何更改数据库表? 通过创建和应用迁移。
While testing your Bitcoin tracker, you realize that you made a mistake. People are selling fractions of a Bitcoin, so the field volume
should be of the type DecimalField
instead of PositiveIntegerField
.
在测试您的比特币跟踪器时,您意识到自己犯了一个错误。 人们正在出售比特币的零头,因此字段volume
应为DecimalField
类型,而不是PositiveIntegerField
类型。
Let’s change the model to look like this:
让我们将模型更改为如下所示:
Without migrations, you would have to figure out the SQL syntax to turn a PositiveIntegerField
into a DecimalField
. Luckily, Django will handle that for you. Just tell it to make migrations:
如果不进行迁移,则必须弄清楚SQL语法才能将PositiveIntegerField
转换为DecimalField
。 幸运的是,Django将为您处理。 只需告诉它进行迁移即可:
$ python manage.py makemigrations
$ python manage.py makemigrations
Migrations for 'historical_data':
Migrations for 'historical_data':
historical_data/migrations/0002_auto_20181112_1950.py
historical_data/migrations/0002_auto_20181112_1950.py
- Alter field volume on pricehistory
- Alter field volume on pricehistory
Note: The name of the migration file (0002_auto_20181112_1950.py
) is based on the current time and will be different if you follow along on your system.
注意:迁移文件的名称( 0002_auto_20181112_1950.py
)基于当前时间,如果您继续使用系统,则该名称将有所不同。
Now you apply this migration to your database:
现在,您将此迁移应用于数据库:
The migration has been applied successfully, so you can use dbshell
to verify that the changes had an effect:
迁移已成功应用,因此您可以使用dbshell
来验证更改是否有效:
$ python manage.py dbshell
$ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
Enter ".help" for usage hints.
sqlite> .schema --indent historical_data_pricehistory
sqlite> .schema --indent historical_data_pricehistory
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory" (
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date" datetime NOT NULL,
"date" datetime NOT NULL,
"price" decimal NOT NULL,
"price" decimal NOT NULL,
"volume" decimal NOT NULL
"volume" decimal NOT NULL
);
);
If you compare the new schema with the schema you saw earlier, you will notice that the type of the volume
column has changed from integer
to decimal
to reflect the change of the volume
field in the model from PositiveIntegerField
to DecimalField
.
如果将新架构与之前看到的架构进行比较,您会发现volume
列的类型已从integer
更改为decimal
以反映模型中的volume
字段从PositiveIntegerField
更改为DecimalField
。
列出迁移 (Listing Out Migrations)
If you want to know what migrations exist in a Django project, you don’t have to dig trough the migrations
directories of your installed apps. You can use the showmigrations
command:
如果您想知道Django项目中存在哪些迁移,则无需深入研究已安装应用程序的migrations
目录。 您可以使用showmigrations
命令:
This lists all apps in the project and the migrations associated with each app. Also, it will put a big X
next to the migrations that have already been applied.
这列出了项目中的所有应用程序以及与每个应用程序关联的迁移。 另外,它将在已应用的迁移旁边放置一个大X
For our little example, the showmigrations
command is not particularly exciting, but it comes in handy when you start working on an existing code base or work in a team where you are not the only person adding migrations.
对于我们的小例子, showmigrations
命令并不是特别令人兴奋,但是当您开始使用现有代码库或不是唯一添加迁移的人的团队工作时,它会派上用场。
取消应用迁移 (Unapplying Migrations)
Now you know how to make changes to your database schema by creating and applying migrations. At some point, you might want to undo changes and switch back to an earlier database schema because you:
现在,您知道如何通过创建和应用迁移来更改数据库架构。 在某个时候,您可能要撤消更改并切换回较早的数据库架构,因为您:
- Want to test a migration a colleague wrote
- Realize that a change you made was a bad idea
- Work on multiple features with different database changes in parallel
- Want to restore a backup that was created when the database still had an older schema
- 想测试一位同事写的迁移
- 意识到所做的更改不是一个好主意
- 并行处理具有不同数据库更改的多个功能
- 想要还原数据库仍具有较旧架构时创建的备份
Luckily, migrations don’t have to be a one-way street. In many cases, the effects of a migration can be undone by unapplying a migration. To unapply a migration, you have to call migrate
with the name of the app and the name of the migration before the migration you want to unapply.
幸运的是,迁移不必走单向路。 在许多情况下,可以通过不应用迁移来撤消迁移的影响。 要取消应用迁移,您必须在要取消应用迁移之前使用应用程序名称和migrate
名称来调用migrate
。
If you want to revert the migration 0002_auto_20181112_1950
in your historical_data
app, you have to pass 0001_initial
as an argument to the migrate
command:
如果你想恢复迁移0002_auto_20181112_1950
在historical_data
的应用程序,你必须通过0001_initial
作为参数传递给migrate
命令:
$ python manage.py migrate historical_data 0001_initial
$ python manage.py migrate historical_data 0001_initial
Operations to perform:
Operations to perform:
Target specific migration: 0001_initial, from historical_data
Target specific migration: 0001_initial, from historical_data
Running migrations:
Running migrations:
Rendering model states... DONE
Rendering model states... DONE
Unapplying historical_data.0002_auto_20181112_1950... OK
Unapplying historical_data.0002_auto_20181112_1950... OK
The migration has been unapplied, meaning that the changes to the database have been reversed.
尚未应用迁移,这意味着对数据库的更改已撤消。
Unapplying a migration does not remove its migration file. The next time you run the migrate
command, the migration will be applied again.
取消应用迁移不会删除其迁移文件。 您运行的下一次migrate
命令,迁移将再次应用。
Caution: Don’t confuse unapplying migrations with the undo operation you are used to from your favorite text editor.
警告:不要将未应用的迁移与您习惯从喜欢的文本编辑器中执行的撤消操作混淆。
Not all database operations can be completely reverted. If you remove a field from a model, create a migration, and apply it, Django will remove the respective column from the database.
并非所有数据库操作都可以完全还原。 如果您从模型中删除字段,创建迁移并应用它,则Django将从数据库中删除相应的列。
Unapplying that migration will re-create the column, but it won’t bring back the data that was stored in that column!
取消应用该迁移将重新创建该列,但不会恢复存储在该列中的数据!
When you’re dealing with migration names, Django saves you a few keystrokes by not forcing you to spell out the whole name of the migration. It needs just enough of the name to identify it uniquely.
在处理迁移名称时,Django不会强迫您拼写迁移的全名,从而节省了一些按键操作。 它只需要足够的名称就可以唯一地标识它。
In the previous example, it would have been enough to run python manage.py migrate historical_data 0001
.
在前面的示例中,运行python manage.py migrate historical_data 0001
就足够了。
命名迁移 (Naming Migrations)
In the above example, Django came up with a name for the migration based on the timestamp—something like *0002_auto_20181112_1950
. If you’re not happy with that, then you can use the --name
parameter to provide a custom name (without the .py
extension).
在上面的示例中,Django根据时间戳记为迁移提供了一个名称,例如*0002_auto_20181112_1950
。 如果您对此不满意,则可以使用--name
参数提供自定义名称(不带.py
扩展名)。
To try that out, you first have to remove the old migration. You have already unapplied it, so you can safely delete the file:
要尝试该方法,您首先必须删除旧的迁移。 您已经取消应用该文件,因此可以安全地删除该文件:
Now you can recreate it with a more descriptive name:
现在,您可以使用更具描述性的名称来重新创建它:
$ ./manage.py makemigrations historical_data --name 0002_switch_to_decimals
$ ./manage.py makemigrations historical_data --name 0002_switch_to_decimals
This will create the same migration as before except with the new name of 0002_switch_to_decimals
.
除了使用新名称0002_switch_to_decimals
之外,这将创建与以前相同的迁移。
结论 (Conclusion)
You covered quite a bit of ground in this tutorial and learned the fundamentals of Django migrations.
您在本教程中涵盖了相当多的基础知识,并了解了Django迁移的基础知识。
To recap, the basic steps to use Django migrations look like this:
回顾一下,使用Django迁移的基本步骤如下所示:
- Create or update a model
- Run
./manage.py makemigrations <app_name>
- Run
./manage.py migrate
to migrate everything or./manage.py migrate <app_name>
to migrate an individual app - Repeat as necessary
- 创建或更新模型
- 运行
./manage.py makemigrations <app_name>
- 运行
./manage.py migrate
以迁移所有内容,或./manage.py migrate <app_name>
迁移单个应用程序 - 根据需要重复
That’s it! This workflow will work the majority of the time, but if things don’t work out as expected, you also know how to list and unapply migrations.
而已! 此工作流程大部分时间都可以正常工作,但是如果事情没有按预期进行,您还知道如何列出和取消应用迁移。
If you previously created and modified your database tables with hand-written SQL, you have now become much more efficient by delegating this work to Django migrations.
如果您以前使用手写SQL创建和修改数据库表,那么现在通过将这项工作委派给Django迁移,您的工作效率将大大提高。
In the next tutorial in this series, you will dig deeper into the topic and learn how Django Migrations work under the hood.
在本系列的下一篇教程中,您将更深入地探讨该主题,并了解Django Migrations的工作原理 。
Free Bonus: Click here to get access to a free Django Learning Resources Guide (PDF) that shows you tips and tricks as well as common pitfalls to avoid when building Python + Django web applications.
免费红利: 单击此处可获得免费的Django学习资源指南(PDF) ,其中显示了一些技巧和窍门,以及在构建Python + Django Web应用程序时应避免的常见陷阱。
Cheers!
干杯!
视频 (Video)
翻译自: https://www.pybloggers.com/2019/01/django-migrations-a-primer/
django迁移