{"title":"迁移操作","version":"6.0","locale":"zh-hans","docname":"ref/migration-operations","url":"/zh-hans/6.0/ref/migration-operations/","canonical":"https://djangodocs.dev/zh-hans/6.0/ref/migration-operations/","summary":"迁移文件由一个或多个 Operation 组成，这些对象声明性地记录了迁移对数据库的作用。 Django 也使用这些 Operation 对象来计算出你的模型在历史上的样子，并计算出自上次迁移以来你对模型做了哪些改变，这样它就可以自动写出你的迁移；这就是为什么它们是声明式的，因为这意味着 Django…","html":"<span id=\"migration-operations\"></span><h1>迁移操作<a class=\"heading-anchor\" href=\"#module-django.db.migrations.operations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>迁移文件由一个或多个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 组成，这些对象声明性地记录了迁移对数据库的作用。</p>\n<p>Django 也使用这些 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 对象来计算出你的模型在历史上的样子，并计算出自上次迁移以来你对模型做了哪些改变，这样它就可以自动写出你的迁移；这就是为什么它们是声明式的，因为这意味着 Django 可以很容易地将它们全部加载到内存中，并在不接触数据库的情况下运行它们，以计算出你的项目应该是什么样子。</p>\n<p>还有更专业的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 对象，用于诸如 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/migrations/#data-migrations\"><span class=\"std std-ref\">数据迁移</span></a> 和进阶的手动数据库操作。如果你想封装你经常进行的自定义更改，你也可以编写自己的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 类。</p>\n<p>如果你需要一个空的迁移文件来编写你自己的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 对象，使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">python</span> <span class=\"pre\">manage.py</span> <span class=\"pre\">makemigrations</span> <span class=\"pre\">--empty</span> <span class=\"pre\">yourappname</span></code>，但是要注意手动添加架构变化的操作会混淆迁移自动检测器，使 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> 的运行结果输出错误的代码。</p>\n<p>所有的 Django 核心操作都可以在 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.migrations.options</span></code> 模块中找到。</p>\n<p>关于介绍性材料，见 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/migrations/\"><span class=\"doc\">迁移专题指南</span></a>。</p>\n<section id=\"schema-operations\">\n<h2>架构操作<a class=\"heading-anchor\" href=\"#schema-operations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"createmodel\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">CreateModel</span></code><a class=\"heading-anchor\" href=\"#createmodel\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.CreateModel\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">CreateModel</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">fields</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">options</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">bases</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">managers</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.CreateModel\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>在项目历史中创建一个新的模型，并在数据库中创建与之匹配的相应表。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 是模型名称，如在 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code> 文件中写的那样。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">fields</span></code> 是一个由 <code class=\"docutils literal notranslate\"><span class=\"pre\">(field_name,</span> <span class=\"pre\">field_instance)</span></code> 组成的2二元元组的列表。字段实例应该是一个未绑定的字段（所以只是 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.CharField(...)</span></code>，而不是取自另一个模型的字段）。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">options</span></code> 是模型 <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 类的可选值字典。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">bases</span></code> 是一个可选的其他类的列表，让这个模型继承；它既可以包含类对象，也可以包含格式为 <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;appname.ModelName&quot;</span></code> 的字符串，如果你想依赖另一个模型（所以你继承了历史版本）。如果没有提供，它默认为从标准的 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.Model</span></code> 继承。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">managers</span></code> 需要一个由 <code class=\"docutils literal notranslate\"><span class=\"pre\">(manager_name,</span> <span class=\"pre\">manager_instance)</span></code> 组成的二元元组的列表。在迁移过程中，列表中的第一个管理器将是这个模型的默认管理器。</p>\n</section>\n<section id=\"deletemodel\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">DeleteModel</span></code><a class=\"heading-anchor\" href=\"#deletemodel\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.DeleteModel\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">DeleteModel</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.DeleteModel\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>从项目历史中删除模型，并从数据库中删除它的表。</p>\n</section>\n<section id=\"renamemodel\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RenameModel</span></code><a class=\"heading-anchor\" href=\"#renamemodel\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RenameModel\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RenameModel</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">old_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">new_name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RenameModel\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>将模型从旧名称改名为新名称。</p>\n<p>如果你一次更改了模型的名称和相当多的字段，你可能必须手动添加这个；对自动检测器来说，这看起来就像你删除了一个使用旧名称的模型，并添加了一个使用不同名称的新模型，它创建的迁移将丢失旧表中的任何数据。</p>\n</section>\n<section id=\"altermodeltable\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterModelTable</span></code><a class=\"heading-anchor\" href=\"#altermodeltable\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterModelTable\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterModelTable</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">table</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterModelTable\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>更改模型的表名（<code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 子类上的 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/options/#django.db.models.Options.db_table\" title=\"django.db.models.Options.db_table\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">db_table</span></code></a> 选项）。</p>\n</section>\n<section id=\"altermodeltablecomment\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterModelTableComment</span></code><a class=\"heading-anchor\" href=\"#altermodeltablecomment\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterModelTableComment\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterModelTableComment</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">table_comment</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterModelTableComment\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>更改模型的表注释（位于 <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 子类上的 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/options/#django.db.models.Options.db_table_comment\" title=\"django.db.models.Options.db_table_comment\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">db_table_comment</span></code></a> 选项）。</p>\n</section>\n<section id=\"alteruniquetogether\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterUniqueTogether</span></code><a class=\"heading-anchor\" href=\"#alteruniquetogether\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterUniqueTogether\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterUniqueTogether</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">unique_together</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterUniqueTogether\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>改变模型的唯一约束集（<code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 子类上的 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/options/#django.db.models.Options.unique_together\" title=\"django.db.models.Options.unique_together\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">unique_together</span></code></a> 选项）。</p>\n</section>\n<section id=\"alterindextogether\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterIndexTogether</span></code><a class=\"heading-anchor\" href=\"#alterindextogether\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterIndexTogether\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterIndexTogether</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">index_together</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterIndexTogether\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>更改模型的自定义索引集合（位于 <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 子类上的 <code class=\"docutils literal notranslate\"><span class=\"pre\">index_together</span></code> 选项）。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterIndexTogether</span></code> 官方上仅支持用于 Django 4.2 之前的迁移文件。出于向后兼容的原因，它仍然是公共 API 的一部分，没有计划弃用或移除它，但不应在新的迁移中使用它。而应该使用 <a class=\"reference internal\" href=\"#django.db.migrations.operations.AddIndex\" title=\"django.db.migrations.operations.AddIndex\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AddIndex</span></code></a> 和 <a class=\"reference internal\" href=\"#django.db.migrations.operations.RemoveIndex\" title=\"django.db.migrations.operations.RemoveIndex\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RemoveIndex</span></code></a> 操作。</p>\n</aside>\n</section>\n<section id=\"alterorderwithrespectto\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterOrderWithRespectTo</span></code><a class=\"heading-anchor\" href=\"#alterorderwithrespectto\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterOrderWithRespectTo\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterOrderWithRespectTo</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">order_with_respect_to</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterOrderWithRespectTo\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>生成或删除 <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 子类上的 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/options/#django.db.models.Options.order_with_respect_to\" title=\"django.db.models.Options.order_with_respect_to\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">order_with_respect_to</span></code></a> 选项所需的 <code class=\"docutils literal notranslate\"><span class=\"pre\">_order</span></code> 列。</p>\n</section>\n<section id=\"altermodeloptions\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterModelOptions</span></code><a class=\"heading-anchor\" href=\"#altermodeloptions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterModelOptions\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterModelOptions</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">options</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterModelOptions\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>存储对各种模型选项的更改（模型 <code class=\"docutils literal notranslate\"><span class=\"pre\">Meta</span></code> 上的设置），如 <code class=\"docutils literal notranslate\"><span class=\"pre\">permissions</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">verbose_name</span></code>。不影响数据库，但会将这些更改持久化，供 <a class=\"reference internal\" href=\"#django.db.migrations.operations.RunPython\" title=\"django.db.migrations.operations.RunPython\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunPython</span></code></a> 实例使用。<code class=\"docutils literal notranslate\"><span class=\"pre\">options</span></code> 应该是一个将选项名映射到值的字典。</p>\n</section>\n<section id=\"altermodelmanagers\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterModelManagers</span></code><a class=\"heading-anchor\" href=\"#altermodelmanagers\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterModelManagers\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterModelManagers</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">managers</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterModelManagers\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>改变迁移期间可用的管理器。</p>\n</section>\n<section id=\"addfield\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code><a class=\"heading-anchor\" href=\"#addfield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AddField\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AddField</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">preserve_default</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AddField\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>为模型添加一个字段。<code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 是模型的名称，<code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 是字段的名称，<code class=\"docutils literal notranslate\"><span class=\"pre\">field</span></code> 是一个未绑定的字段实例（你会在 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code> 中的字段声明中放入的东西——例如，<code class=\"docutils literal notranslate\"><span class=\"pre\">models.IntegerField(null=True)</span></code>）。</p>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">preserve_default</span></code> argument indicates whether the field's default\nvalue is permanent and should be baked into the project state (<code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>),\nor if it is temporary and just for this migration (<code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>) - usually\nbecause the migration is adding a non-nullable field to a table and needs\na default value to put into existing rows. It does not affect the behavior\nof setting defaults in the database directly.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>在旧的数据库中，添加一个具有默认值的字段可能会导致表的完全重写。即使是对于可空字段，也会发生这种情况，可能会对性能产生负面影响。为了避免这种情况，应采取以下步骤。</p>\n<ul class=\"simple\">\n<li><p>添加可空字段，不含默认值，并运行 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> 命令。这应该会产生一个带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code> 操作的迁移。</p></li>\n<li><p>将默认值添加到你的字段中，然后运行:djadmin:makemigrations 命令。这应该会生成一个带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">AlterField</span></code> 操作的迁移。</p></li>\n</ul>\n</aside>\n</section>\n<section id=\"removefield\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RemoveField</span></code><a class=\"heading-anchor\" href=\"#removefield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RemoveField\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RemoveField</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RemoveField\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>从模型中删除一个字段。</p>\n<p>请记住，当反向迁移时，这实际上是向模型添加一个字段。如果字段是可空的，或者它有一个默认值，可以用来填充重新创建的列，那么这个操作是可逆的（除了任何数据损失，这是不可逆的）。如果字段不可为空，也没有默认值，则该操作是不可逆的。</p>\n<aside class=\"version-note version-changed\" data-version=\"6.0\">\n<p class=\"version-note-title\">Changed in Django 6.0</p><p><a class=\"reference internal\" href=\"/zh-hans/6.0/ref/schema-editor/#django.db.backends.base.schema.BaseDatabaseSchemaEditor\" title=\"django.db.backends.base.schema.BaseDatabaseSchemaEditor\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseDatabaseSchemaEditor</span></code></a> and\nPostgreSQL backends no longer use <code class=\"docutils literal notranslate\"><span class=\"pre\">CASCADE</span></code> to delete dependent related\ndatabase objects, such as views. Any dependent objects that are not managed\nby Django may need to be removed manually before running <code class=\"docutils literal notranslate\"><span class=\"pre\">RemoveField</span></code>.</p>\n</aside>\n</section>\n<section id=\"alterfield\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterField</span></code><a class=\"heading-anchor\" href=\"#alterfield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterField\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterField</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">preserve_default</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterField\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>改变字段的定义，包括改变其类型、<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">null</span></code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.Field.unique\" title=\"django.db.models.Field.unique\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">unique</span></code></a>、<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.Field.db_column\" title=\"django.db.models.Field.db_column\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">db_column</span></code></a> 等字段属性。</p>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">preserve_default</span></code> argument indicates whether the field's default\nvalue is permanent and should be baked into the project state (<code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>),\nor if it is temporary and just for this migration (<code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>) - usually\nbecause the migration is altering a nullable field to a non-nullable one and\nneeds a default value to put into existing rows. It does not affect the\nbehavior of setting defaults in the database directly.</p>\n<p>请注意，并不是所有的数据库都可以进行所有的更改——例如，在大多数数据库中，你不能将像 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.TextField()</span></code> 这样的文本型字段改为像 <code class=\"docutils literal notranslate\"><span class=\"pre\">models.IntegerField()</span></code> 这样的数字型字段。</p>\n</section>\n<section id=\"renamefield\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RenameField</span></code><a class=\"heading-anchor\" href=\"#renamefield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RenameField\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RenameField</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">old_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">new_name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RenameField\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>改变一个字段的名称（除非设置了 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.Field.db_column\" title=\"django.db.models.Field.db_column\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">db_column</span></code></a>，否则改变其列名）。</p>\n</section>\n<section id=\"addindex\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AddIndex</span></code><a class=\"heading-anchor\" href=\"#addindex\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AddIndex\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AddIndex</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">index</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AddIndex\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>在数据库表中为模型创建一个带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 的索引。index 是 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/indexes/#django.db.models.Index\" title=\"django.db.models.Index\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Index</span></code></a> 类的一个实例。</p>\n</section>\n<section id=\"removeindex\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RemoveIndex</span></code><a class=\"heading-anchor\" href=\"#removeindex\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RemoveIndex\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RemoveIndex</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RemoveIndex\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>从带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 的模型中删除名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 的索引。</p>\n</section>\n<section id=\"renameindex\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RenameIndex</span></code><a class=\"heading-anchor\" href=\"#renameindex\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RenameIndex\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RenameIndex</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">new_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">old_name</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">old_fields</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RenameIndex\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>重命名数据库中具有 <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 的模型的索引。只能提供 <code class=\"docutils literal notranslate\"><span class=\"pre\">old_name</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">old_fields</span></code> 中的一个。<code class=\"docutils literal notranslate\"><span class=\"pre\">old_fields</span></code> 是一个字符串的可迭代对象，通常对应于 <code class=\"docutils literal notranslate\"><span class=\"pre\">index_together</span></code> 的字段（Django 5.1 之前的选项）。</p>\n<p>On databases that don't support an index renaming statement (SQLite), the\noperation will drop and recreate the index, which can be expensive.</p>\n</section>\n<section id=\"addconstraint\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AddConstraint</span></code><a class=\"heading-anchor\" href=\"#addconstraint\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AddConstraint\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AddConstraint</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">constraint</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AddConstraint\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>在数据库表中为带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 的模型创建一个 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/constraints/\"><span class=\"doc\">约束</span></a>。</p>\n</section>\n<section id=\"removeconstraint\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RemoveConstraint</span></code><a class=\"heading-anchor\" href=\"#removeconstraint\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RemoveConstraint\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RemoveConstraint</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RemoveConstraint\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>从带有 <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> 的模型中删除名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 的约束。</p>\n</section>\n<section id=\"alterconstraint\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">AlterConstraint</span></code><a class=\"heading-anchor\" href=\"#alterconstraint\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"5.2\">\n<p class=\"version-note-title\">New in Django 5.2</p></aside>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.AlterConstraint\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">AlterConstraint</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">model_name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">constraint</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.AlterConstraint\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Alters the constraint named <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> of the model with <code class=\"docutils literal notranslate\"><span class=\"pre\">model_name</span></code> with the\nnew <code class=\"docutils literal notranslate\"><span class=\"pre\">constraint</span></code> without affecting the database.</p>\n</section>\n</section>\n<section id=\"special-operations\">\n<h2>特殊操作<a class=\"heading-anchor\" href=\"#special-operations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"runsql\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code><a class=\"heading-anchor\" href=\"#runsql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RunSQL\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RunSQL</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sql</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">reverse_sql</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">state_operations</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">hints</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">elidable</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RunSQL\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>允许在数据库上运行任意 SQL——这对于 Django 不直接支持的数据库后端高级功能非常有用。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_sql</span></code> （如果提供），应该是要在数据库中运行的 SQL 字符串。在大多数数据库后端（除了 PostgreSQL），Django 会在执行 SQL 语句之前将其分割成独立的语句。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>在 PostgreSQL 和 SQLite上，只有在 <a class=\"reference internal\" href=\"/zh-hans/6.0/howto/writing-migrations/#non-atomic-migrations\"><span class=\"std std-ref\">非原子性迁移</span></a> 中的 SQL 中使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">BEGIN</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">COMMIT</span></code>，才能避免破坏 Django 的事务状态。</p>\n</aside>\n<p>你也可以传递一个字符串或二元元组的列表。后者与 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/db/sql/#executing-custom-sql\"><span class=\"std std-ref\">cursor.execute()</span></a> 一样，用于传递查询和参数。这三种操作是等价的：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunSQL</span><span class=\"p\">(</span><span class=\"s2\">&quot;INSERT INTO musician (name) VALUES (&#39;Reinhardt&#39;);&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunSQL</span><span class=\"p\">([(</span><span class=\"s2\">&quot;INSERT INTO musician (name) VALUES (&#39;Reinhardt&#39;);&quot;</span><span class=\"p\">,</span> <span class=\"kc\">None</span><span class=\"p\">)])</span>\n<span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunSQL</span><span class=\"p\">([(</span><span class=\"s2\">&quot;INSERT INTO musician (name) VALUES (</span><span class=\"si\">%s</span><span class=\"s2\">);&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Reinhardt&quot;</span><span class=\"p\">])])</span>\n</code></pre></div>\n<p>如果你想在查询中包含字面的百分号，如果你传递的是参数，你必须将它们翻倍。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_sql</span></code> 查询是在未应用迁移时执行的。它们应该撤销 <code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code> 查询所做的事情。例如，要撤销上面的插入与删除：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunSQL</span><span class=\"p\">(</span>\n    <span class=\"n\">sql</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s2\">&quot;INSERT INTO musician (name) VALUES (</span><span class=\"si\">%s</span><span class=\"s2\">);&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Reinhardt&quot;</span><span class=\"p\">])],</span>\n    <span class=\"n\">reverse_sql</span><span class=\"o\">=</span><span class=\"p\">[(</span><span class=\"s2\">&quot;DELETE FROM musician where name=</span><span class=\"si\">%s</span><span class=\"s2\">;&quot;</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Reinhardt&quot;</span><span class=\"p\">])],</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_sql</span></code> 是 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> （默认），则 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code> 操作是不可逆的。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">state_operations</span></code> 参数允许你提供在项目状态方面相当于 SQL 的操作。例如，如果你正在手动创建一个列，你应该在这里传递一个包含 <code class=\"docutils literal notranslate\"><span class=\"pre\">AddField</span></code> 操作的列表，这样自动检测器仍然有一个最新的模型状态。如果你不这样做，当你下次运行 <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code> 时，它不会看到任何添加该字段的操作，所以会尝试再次运行它。例如：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunSQL</span><span class=\"p\">(</span>\n    <span class=\"s2\">&quot;ALTER TABLE musician ADD COLUMN name varchar(255) NOT NULL;&quot;</span><span class=\"p\">,</span>\n    <span class=\"n\">state_operations</span><span class=\"o\">=</span><span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">AddField</span><span class=\"p\">(</span>\n            <span class=\"s2\">&quot;musician&quot;</span><span class=\"p\">,</span>\n            <span class=\"s2\">&quot;name&quot;</span><span class=\"p\">,</span>\n            <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">255</span><span class=\"p\">),</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">],</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>可选的 <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code> 参数将作为 <code class=\"docutils literal notranslate\"><span class=\"pre\">**hints</span></code> 传递给数据库路由器的 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/db/multi-db/#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code></a> 方法，以帮助它们做出路由决策。参见 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/db/multi-db/#topics-db-multi-db-hints\"><span class=\"std std-ref\">提示</span></a> 了解更多关于数据库提示的细节。</p>\n<p>可选的 <code class=\"docutils literal notranslate\"><span class=\"pre\">elidable</span></code> 参数决定了当 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/migrations/#migration-squashing\"><span class=\"std std-ref\">压缩迁移</span></a> 时，是否会删除（elided）该操作。</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RunSQL.noop\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">RunSQL.</span></span><span class=\"sig-name descname\"><span class=\"pre\">noop</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RunSQL.noop\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>当你希望操作在给定的方向上不做任何事情时，将 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunSQL.noop</span></code> 属性传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_sql</span></code>。这在使操作可逆时特别有用。</p>\n</dd></dl>\n\n</section>\n<section id=\"runpython\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code><a class=\"heading-anchor\" href=\"#runpython\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RunPython\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">RunPython</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">code</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">reverse_code</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">atomic</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">hints</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">elidable</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RunPython\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>在历史上下文中运行自定义 Python 代码。<code class=\"docutils literal notranslate\"><span class=\"pre\">code</span></code> （如果提供了 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_code</span></code>）应该是可调用的对象，接受两个参数；第一个是 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.app.registry.Apps</span></code> 的实例，包含与操作在项目历史中的位置相匹配的历史模型，第二个是 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/schema-editor/#django.db.backends.base.schema.BaseDatabaseSchemaEditor\" title=\"django.db.backends.base.schema.BaseDatabaseSchemaEditor\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SchemaEditor</span></code></a> 的实例。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_code</span></code> 参数在取消应用迁移时被调用。这个可调用对象参数应该撤销在 <code class=\"docutils literal notranslate\"><span class=\"pre\">code</span></code> 可调用对象参数中所做的事情，这样迁移才是可逆的。如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_code</span></code> 是``None`` （默认），则 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作是不可逆的。</p>\n<p>可选的 <code class=\"docutils literal notranslate\"><span class=\"pre\">hints</span></code> 参数将作为 <code class=\"docutils literal notranslate\"><span class=\"pre\">**hints</span></code> 传递给数据库路由器的 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/db/multi-db/#allow_migrate\" title=\"allow_migrate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">allow_migrate()</span></code></a> 方法，以帮助它们做出路由决策。参见 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/db/multi-db/#topics-db-multi-db-hints\"><span class=\"std std-ref\">提示</span></a> 了解更多关于数据库提示的细节。</p>\n<p>可选的 <code class=\"docutils literal notranslate\"><span class=\"pre\">elidable</span></code> 参数决定了当 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/migrations/#migration-squashing\"><span class=\"std std-ref\">压缩迁移</span></a> 时，是否会删除（elided）该操作。</p>\n<p>建议你把这些代码写成一个单独的函数，放在迁移文件中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">Migration</span></code> 类上面，然后传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code>。下面是一个使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 在 <code class=\"docutils literal notranslate\"><span class=\"pre\">Country</span></code> 模型上创建一些初始对象的例子：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">migrations</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">forwards_func</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"c1\"># We get the model from the versioned app registry;</span>\n    <span class=\"c1\"># if we directly import it, it&#39;ll be the wrong version</span>\n    <span class=\"n\">Country</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Country&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">db_alias</span> <span class=\"o\">=</span> <span class=\"n\">schema_editor</span><span class=\"o\">.</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">alias</span>\n    <span class=\"n\">Country</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"n\">db_alias</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">bulk_create</span><span class=\"p\">(</span>\n        <span class=\"p\">[</span>\n            <span class=\"n\">Country</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;USA&quot;</span><span class=\"p\">,</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s2\">&quot;us&quot;</span><span class=\"p\">),</span>\n            <span class=\"n\">Country</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;France&quot;</span><span class=\"p\">,</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s2\">&quot;fr&quot;</span><span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n    <span class=\"p\">)</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">reverse_func</span><span class=\"p\">(</span><span class=\"n\">apps</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">):</span>\n    <span class=\"c1\"># forwards_func() creates two Country instances,</span>\n    <span class=\"c1\"># so reverse_func() should delete them.</span>\n    <span class=\"n\">Country</span> <span class=\"o\">=</span> <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">get_model</span><span class=\"p\">(</span><span class=\"s2\">&quot;myapp&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Country&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">db_alias</span> <span class=\"o\">=</span> <span class=\"n\">schema_editor</span><span class=\"o\">.</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">alias</span>\n    <span class=\"n\">Country</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"n\">db_alias</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;USA&quot;</span><span class=\"p\">,</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s2\">&quot;us&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n    <span class=\"n\">Country</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">using</span><span class=\"p\">(</span><span class=\"n\">db_alias</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;France&quot;</span><span class=\"p\">,</span> <span class=\"n\">code</span><span class=\"o\">=</span><span class=\"s2\">&quot;fr&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">delete</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Migration</span><span class=\"p\">(</span><span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">Migration</span><span class=\"p\">):</span>\n    <span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n    <span class=\"n\">operations</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"n\">migrations</span><span class=\"o\">.</span><span class=\"n\">RunPython</span><span class=\"p\">(</span><span class=\"n\">forwards_func</span><span class=\"p\">,</span> <span class=\"n\">reverse_func</span><span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n</code></pre></div>\n<p>这通常是你用来创建 <a class=\"reference internal\" href=\"/zh-hans/6.0/topics/migrations/#data-migrations\"><span class=\"std std-ref\">数据迁移</span></a> 的操作，运行自定义数据更新和更改，以及其他任何你需要访问 ORM 和／或 Python 代码的操作。</p>\n<p>就像 <a class=\"reference internal\" href=\"#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code></a> 一样，确保如果你在这里改变模式，你要么是在 Django 模型系统的范围外进行（例如触发器），要么你使用 <a class=\"reference internal\" href=\"#django.db.migrations.operations.SeparateDatabaseAndState\" title=\"django.db.migrations.operations.SeparateDatabaseAndState\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SeparateDatabaseAndState</span></code></a> 来添加操作，以反映你对模型状态的改变——否则，过时的 ORM 和自动检测器将停止正常工作。</p>\n<p>默认情况下，<code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 将在不支持 DDL 事务的数据库（例如 MySQL 和 Oracle）的事务中运行其内容。这应该是安全的，但如果你试图使用这些后端提供的 <code class=\"docutils literal notranslate\"><span class=\"pre\">schema_editor</span></code> 可能会导致崩溃；在这种情况下，将 <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic=False</span></code> 传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作。</p>\n<p>在支持 DDL 事务的数据库上（SQLite 和 PostgreSQL），<code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作除了为每次迁移创建的事务外，不会自动添加任何事务。因此，例如在 PostgreSQL 上，你应该避免在同一个迁移中把架构变化和 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作结合起来，否则你可能会遇到 <code class=\"docutils literal notranslate\"><span class=\"pre\">OperationalError:</span> <span class=\"pre\">cannot</span> <span class=\"pre\">ALTER</span> <span class=\"pre\">TABLE</span> <span class=\"pre\">&quot;mytable&quot;</span> <span class=\"pre\">because</span> <span class=\"pre\">it</span> <span class=\"pre\">has</span> <span class=\"pre\">pending</span> <span class=\"pre\">trigger</span> <span class=\"pre\">events</span></code> 这样的错误。</p>\n<p>如果你有一个不同的数据库，并且不确定它是否支持 DDL 事务，检查 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.connection.features.can_rollback_ddl</span></code> 属性。</p>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作是 <a class=\"reference internal\" href=\"/zh-hans/6.0/howto/writing-migrations/#non-atomic-migrations\"><span class=\"std std-ref\">非原子性的迁移</span></a> 的一部分，那么只有当 <code class=\"docutils literal notranslate\"><span class=\"pre\">atomic=True</span></code> 传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 操作时，该操作才会在事务中执行。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython</span></code> 不会为你神奇地改变模型的连接；你调用的任何模型方法将转到默认的数据库，除非你给它们当前的数据库别名（可从 <code class=\"docutils literal notranslate\"><span class=\"pre\">schema_editor.connection.alias</span></code> 中获得，其中 <code class=\"docutils literal notranslate\"><span class=\"pre\">schema_editor</span></code> 是你函数的第二个参数）。</p>\n</aside>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.RunPython.noop\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">static</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">RunPython.</span></span><span class=\"sig-name descname\"><span class=\"pre\">noop</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.RunPython.noop\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>当你希望操作在给定的方向上不做任何事情时，将 <code class=\"docutils literal notranslate\"><span class=\"pre\">RunPython.noop</span></code> 方法传递给 <code class=\"docutils literal notranslate\"><span class=\"pre\">code</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">reverse_code</span></code>。这在使操作可逆时特别有用。</p>\n</dd></dl>\n\n</section>\n<section id=\"separatedatabaseandstate\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">SeparateDatabaseAndState</span></code><a class=\"heading-anchor\" href=\"#separatedatabaseandstate\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.SeparateDatabaseAndState\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">SeparateDatabaseAndState</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">database_operations</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">state_operations</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.SeparateDatabaseAndState\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>一个高度专业化的操作，让你混合和匹配数据库（架构改变）和状态（自动检测器支持）方面的操作。</p>\n<p>它接受两个操作列表。当要求它应用状态时，它将使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">state_operations</span></code> 列表（这是 <a class=\"reference internal\" href=\"#django.db.migrations.operations.RunSQL\" title=\"django.db.migrations.operations.RunSQL\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RunSQL</span></code></a> 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">state_operations</span></code> 参数的通用版本）。当要求它对数据库进行更改时，它将使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">database_operations</span></code> 列表。</p>\n<p>如果数据库的实际状态和 Django 的状态视图不同步，就会破坏迁移框架，甚至导致数据丢失。值得谨慎行事，仔细检查你的数据库和状态操作。你可以使用 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-sqlmigrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">sqlmigrate</span></code></a> 和 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-dbshell\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dbshell</span></code></a> 来检查你的数据库操作。你可以使用 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a>，特别是使用 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#cmdoption-makemigrations-dry-run\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">--dry-run</span></code></a>，来检查你的状态操作。</p>\n<p>关于使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">SeparateDatabaseAndState</span></code> 的例子，请参见 <span class=\"xref std std-ref\">changing-a-manytomanyfield to use-a-through-model</span>。</p>\n</section>\n</section>\n<section id=\"operation-category\">\n<h2>操作类别<a class=\"heading-anchor\" href=\"#operation-category\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">OperationCategory</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>由 <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code></a> 命令使用的迁移操作类别，用于显示有意义的符号。</p>\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.ADDITION\">\n<span class=\"sig-name descname\"><span class=\"pre\">ADDITION</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.ADDITION\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">+</span></code></p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.REMOVAL\">\n<span class=\"sig-name descname\"><span class=\"pre\">REMOVAL</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.REMOVAL\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">-</span></code></p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.ALTERATION\">\n<span class=\"sig-name descname\"><span class=\"pre\">ALTERATION</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.ALTERATION\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">~</span></code></p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.PYTHON\">\n<span class=\"sig-name descname\"><span class=\"pre\">PYTHON</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.PYTHON\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">p</span></code></p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.SQL\">\n<span class=\"sig-name descname\"><span class=\"pre\">SQL</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.SQL\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">s</span></code></p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.migrations.operations.base.OperationCategory.MIXED\">\n<span class=\"sig-name descname\"><span class=\"pre\">MIXED</span></span><a class=\"heading-anchor\" href=\"#django.db.migrations.operations.base.OperationCategory.MIXED\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>符号</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">?</span></code></p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"writing-your-own\">\n<span id=\"writing-your-own-migration-operation\"></span><h2>自己写<a class=\"heading-anchor\" href=\"#writing-your-own\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>操作有一个相对简单的 API，而且它们被设计成可以让你很容易地编写自己的 API 来补充内置的 Django 的 API。一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">Operation</span></code> 的基本结构是这样的：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.migrations.operations.base</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Operation</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyCustomOperation</span><span class=\"p\">(</span><span class=\"n\">Operation</span><span class=\"p\">):</span>\n    <span class=\"c1\"># If this is False, it means that this operation will be ignored by</span>\n    <span class=\"c1\"># sqlmigrate; if true, it will be run and the SQL collected for its output.</span>\n    <span class=\"n\">reduces_to_sql</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    <span class=\"c1\"># If this is False, Django will refuse to reverse past this operation.</span>\n    <span class=\"n\">reversible</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    <span class=\"c1\"># This categorizes the operation. The corresponding symbol will be</span>\n    <span class=\"c1\"># displayed by the makemigrations command.</span>\n    <span class=\"n\">category</span> <span class=\"o\">=</span> <span class=\"n\">OperationCategory</span><span class=\"o\">.</span><span class=\"n\">ADDITION</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">arg1</span><span class=\"p\">,</span> <span class=\"n\">arg2</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Operations are usually instantiated with arguments in migration</span>\n        <span class=\"c1\"># files. Store the values of them on self for later use.</span>\n        <span class=\"k\">pass</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">state_forwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">):</span>\n        <span class=\"c1\"># The Operation should take the &#39;state&#39; parameter (an instance of</span>\n        <span class=\"c1\"># django.db.migrations.state.ProjectState) and mutate it to match</span>\n        <span class=\"c1\"># any schema changes that have occurred.</span>\n        <span class=\"k\">pass</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">database_forwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">,</span> <span class=\"n\">from_state</span><span class=\"p\">,</span> <span class=\"n\">to_state</span><span class=\"p\">):</span>\n        <span class=\"c1\"># The Operation should use schema_editor to apply any changes it</span>\n        <span class=\"c1\"># wants to make to the database.</span>\n        <span class=\"k\">pass</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">database_backwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">,</span> <span class=\"n\">from_state</span><span class=\"p\">,</span> <span class=\"n\">to_state</span><span class=\"p\">):</span>\n        <span class=\"c1\"># If reversible is True, this is called when the operation is reversed.</span>\n        <span class=\"k\">pass</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">describe</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># This is used to describe what the operation does.</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;Custom Operation&quot;</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">migration_name_fragment</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Optional. A filename part suitable for automatically naming a</span>\n        <span class=\"c1\"># migration containing this operation, or None if not applicable.</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;custom_operation_</span><span class=\"si\">%s</span><span class=\"s2\">_</span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">arg1</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">arg2</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>你可以使用这个模板，并在此基础上进行工作，不过我们建议查看 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.db.migrations.options</span></code> 中内置的 Django 操作——它们涵盖了很多迁移框架半内部方面的例子，比如 <code class=\"docutils literal notranslate\"><span class=\"pre\">ProjectState</span></code> 和用于获取历史模型的模式，以及 <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">state_forwards()</span></code> 中用于突变历史模型的模式。</p>\n<p>注意事项：</p>\n<ul>\n<li><p>你不需要学习太多关于 <code class=\"docutils literal notranslate\"><span class=\"pre\">ProjectState</span></code> 的知识来编写迁移；只需要知道它有一个 <code class=\"docutils literal notranslate\"><span class=\"pre\">apps</span></code> 属性，它提供了对应用程序注册表的访问（然后你可以调用 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_model</span></code>）。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">database_forwards</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">database_backwards</span></code> 都有两个状态传递给它们；这些状态代表了 <code class=\"docutils literal notranslate\"><span class=\"pre\">state_forwards</span></code> 方法本会应用的差异，但为了方便和速度的原因，给了你。</p></li>\n<li><p>如果你想从 <code class=\"docutils literal notranslate\"><span class=\"pre\">database_forwards()</span></code> 或 <code class=\"docutils literal notranslate\"><span class=\"pre\">database_backwards()</span></code> 中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">from_state</span></code> 参数中处理模型类或模型实例，你必须使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">clear_delayed_apps_cache()</span></code> 方法渲染模型状态，以使相关模型可用：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">database_forwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">,</span> <span class=\"n\">from_state</span><span class=\"p\">,</span> <span class=\"n\">to_state</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This operation should have access to all models. Ensure that all models are</span>\n    <span class=\"c1\"># reloaded in case any are delayed.</span>\n    <span class=\"n\">from_state</span><span class=\"o\">.</span><span class=\"n\">clear_delayed_apps_cache</span><span class=\"p\">()</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n<li><p>database_backwards 方法中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">to_state</span></code> 是指 <em>旧</em> 的状态；也就是反向迁移完成后将成为当前状态的状态。</p></li>\n<li><p>你可能会在内置操作上看到 <code class=\"docutils literal notranslate\"><span class=\"pre\">references_model</span></code> 的实现，这是自动检测代码的一部分，对自定义操作并不重要。</p></li>\n</ul>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Warning</p>\n<p>由于性能原因，<code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState.fields.Field</span></code> 中的 <code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Field`</span></code> 实例会在不同的迁移中重复使用。你决不能改变这些实例的属性。如果你需要在 <code class=\"docutils literal notranslate\"><span class=\"pre\">state_forwards()</span></code> 中突变一个字段，你必须从 <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState.fields</span></code> 中删除旧的实例，并在其位置上添加一个新的实例。对于 <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelState.managers</span></code> 中的 <code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Manager`</span></code> 实例也是如此。</p>\n</aside>\n<p>举个例子，让我们做一个加载 PostgreSQL 扩展的操作（其中包含了 PostgreSQL 的一些更令人兴奋的特性）。由于没有改变模型状态，所以它所做的只是运行一条命令：</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.migrations.operations.base</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Operation</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LoadExtension</span><span class=\"p\">(</span><span class=\"n\">Operation</span><span class=\"p\">):</span>\n    <span class=\"n\">reversible</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">name</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">state_forwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">):</span>\n        <span class=\"k\">pass</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">database_forwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">,</span> <span class=\"n\">from_state</span><span class=\"p\">,</span> <span class=\"n\">to_state</span><span class=\"p\">):</span>\n        <span class=\"n\">schema_editor</span><span class=\"o\">.</span><span class=\"n\">execute</span><span class=\"p\">(</span><span class=\"s2\">&quot;CREATE EXTENSION IF NOT EXISTS </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">database_backwards</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">,</span> <span class=\"n\">schema_editor</span><span class=\"p\">,</span> <span class=\"n\">from_state</span><span class=\"p\">,</span> <span class=\"n\">to_state</span><span class=\"p\">):</span>\n        <span class=\"n\">schema_editor</span><span class=\"o\">.</span><span class=\"n\">execute</span><span class=\"p\">(</span><span class=\"s2\">&quot;DROP EXTENSION </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">describe</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;Creates extension </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">migration_name_fragment</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;create_extension_</span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n</code></pre></div>\n</section>","rootId":"module-django.db.migrations.operations","toc":[{"title":"架构操作","anchor":"schema-operations","children":[{"title":"CreateModel","anchor":"createmodel","children":[]},{"title":"DeleteModel","anchor":"deletemodel","children":[]},{"title":"RenameModel","anchor":"renamemodel","children":[]},{"title":"AlterModelTable","anchor":"altermodeltable","children":[]},{"title":"AlterModelTableComment","anchor":"altermodeltablecomment","children":[]},{"title":"AlterUniqueTogether","anchor":"alteruniquetogether","children":[]},{"title":"AlterIndexTogether","anchor":"alterindextogether","children":[]},{"title":"AlterOrderWithRespectTo","anchor":"alterorderwithrespectto","children":[]},{"title":"AlterModelOptions","anchor":"altermodeloptions","children":[]},{"title":"AlterModelManagers","anchor":"altermodelmanagers","children":[]},{"title":"AddField","anchor":"addfield","children":[]},{"title":"RemoveField","anchor":"removefield","children":[]},{"title":"AlterField","anchor":"alterfield","children":[]},{"title":"RenameField","anchor":"renamefield","children":[]},{"title":"AddIndex","anchor":"addindex","children":[]},{"title":"RemoveIndex","anchor":"removeindex","children":[]},{"title":"RenameIndex","anchor":"renameindex","children":[]},{"title":"AddConstraint","anchor":"addconstraint","children":[]},{"title":"RemoveConstraint","anchor":"removeconstraint","children":[]},{"title":"AlterConstraint","anchor":"alterconstraint","children":[]}]},{"title":"特殊操作","anchor":"special-operations","children":[{"title":"RunSQL","anchor":"runsql","children":[]},{"title":"RunPython","anchor":"runpython","children":[]},{"title":"SeparateDatabaseAndState","anchor":"separatedatabaseandstate","children":[]}]},{"title":"操作类别","anchor":"operation-category","children":[]},{"title":"自己写","anchor":"writing-your-own","children":[]}],"breadcrumbs":[{"docname":"ref/index","title":"API 参考","url":"/zh-hans/6.0/ref/"}],"prev":{"docname":"ref/middleware","title":"中间件","url":"/zh-hans/6.0/ref/middleware/"},"next":{"docname":"ref/models/index","title":"模型","url":"/zh-hans/6.0/ref/models/"},"formats":{"html":"/zh-hans/6.0/ref/migration-operations/","markdown":"/zh-hans/6.0/ref/migration-operations.md","json":"/zh-hans/6.0/ref/migration-operations.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/ref/migration-operations.txt","official":"https://docs.djangoproject.com/zh-hans/6.0/ref/migration-operations/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}