百宏设备安装 發表於 2020-12-19 12:24:00

玩转Node.js-Sequelize数据迁移

<p>数据库迁移就像git一样,我们可以使用Sequelize迁移来帮助我们跟踪数据库的更改,并在各个不同时期的数据库状态之间进行切换,使用Sequelize迁移,需要安装 sequelize-cli 工具。</p>
<h2 id="安装sequelize-cli">安装sequelize-cli</h2>
<p>由于<code>sequelize-cli</code>依赖于<code>sequelize</code>包,sequelize又需要使用<code>mysql2</code>包来连接数据库,所以我们需要安装三个包。</p>
<pre><code class="language-shell">npm i sequelize mysql2 sequelize-cli
</code></pre>
<p>如果是局部安装方式的话,安装完成之后进入node_modules目录下面的.bin目录下执行<code>sequelizse-cli</code>命令来测试sequelize-cli是否安装成功。</p>
<p>运行成功会出现下面信息。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122107882-422402973.png" alt="1607738318387" loading="lazy"></p>
<h2 id="初始化项目">初始化项目</h2>
<p>执行<code>sequelize-cli init</code>命令初始化sequelize项目,成功执行之后会创建4个文件夹。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108037-44376869.png" alt="1607738888421" loading="lazy"></p>
<ul>
<li>config:                包含配置文件,它高速CLI如何连接数据库</li>
<li>models:            包含你项目的所有模型</li>
<li>migrations:   包含所有迁移文件</li>
<li>seeders:         包含所有种子文件</li>
</ul>
<p>config文件夹中的<code>config.json</code>配置有3个环境,分别是开始环境、测试环境、生产环境。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108222-927139318.png" alt="1607739072441" loading="lazy"></p>
<h2 id="创建数据库">创建数据库</h2>
<p>sequelize-cli会根据<code>config/config.json</code>里面的环境配置信息自动为我们创建数据库,默认情况会根据开发环境信息进行配置。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108497-689669687.png" alt="1607739581747" loading="lazy"></p>
<p>可以看到数据库成功创建。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108658-1954525330.png" alt="1607739622637" loading="lazy"></p>
<p>删除数据库</p>
<p><code>sequelize-cli db:drop</code>命令会根据配置信息删除数据库。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108784-602062121.png" alt="1607739823236" loading="lazy"></p>
<h2 id="自定义环境变量">自定义环境变量</h2>
<p>1.设置环境变量。</p>
<pre><code class="language-shell">#设置环境变量NODE_ENV的值为home
set NODE_ENV=home
#删除环境变量,此时会得到home
echo %NODE_ENV%
#还原NODE_ENV的环境变量
set NODE_ENV=
</code></pre>
<p>2.在<code>config/config.json</code>中新增一项环境配置。</p>
<pre><code class="language-json">"home": {
    "username": "root",
    "password": "root",
    "database": "c4az6_home",
    "host": "127.0.0.1",
    "dialect": "mysql"
},
</code></pre>
<p>3.再使用sequelize-cli创建数据库就会创建出home环境配置下的数据库了。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122108935-1085354093.png" alt="1607740330502" loading="lazy"></p>
<h2 id="创建模型">创建模型</h2>
<p>使用<code>model:generate</code>或者<code>model:create</code>命令创建一个模型文件</p>
<p>参数:</p>
<ul>
<li>--name:模型名称,必须</li>
<li>--attributes:字段列表,必须</li>
</ul>
<p>参考</p>
<pre><code class="language-shell">sequelize-cli model:create --name User --attributes username:STRING
</code></pre>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122109058-2019119704.png" alt="1607741150172" loading="lazy"></p>
<blockquote>
<p>注意:模型文件是给程序用的,迁移文件和种子文件是给sequelize-cli使用的。</p>
</blockquote>
<h2 id="执行迁移">执行迁移</h2>
<p>所谓迁移,就是对数据库进行结构的创建、升级(修改)等操作。</p>
<p>使用<code>db:migrate</code>会找到迁移文件,然后执行里面的代码创建表和字段,同时会在数据库中创建一个<code>sequelizemeta</code>的表来记录迁移的脚本名称。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122109214-1307896979.png" alt="1607741921213" loading="lazy"></p>
<blockquote>
<p>注意db:migrate不能对相同的表反复迁移,会报错。</p>
</blockquote>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122109447-516666743.png" alt="1607741993158" loading="lazy"></p>
<p>我们可以通过<code>db:migrate:status</code>命令查看迁移文件的状态。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122109665-336142810.png" alt="1607742152284" loading="lazy"></p>
<p>这个时候,如果有新的需求,要新增表,那么可以通过下面步骤实现。</p>
<p>1.首先还是创建模型。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122109814-1019508929.png" alt="1607742284397" loading="lazy"></p>
<p>2.查看状态发现为down,就是未迁移状态。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122110030-978370546.png" alt="1607742353374" loading="lazy"></p>
<p>3.迁移。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122110372-572566961.png" alt="1607742427380" loading="lazy"></p>
<p>4.连接数据库进行查看。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122110549-89116309.png" alt="1607742509909" loading="lazy"></p>
<h2 id="撤销迁移">撤销迁移</h2>
<p><code>db:migrate:undo</code>命令会撤销最近的一次迁移操作,会删除最近一次创建的表,会把<code>sequelizemeta</code>表里面的最近一次记录删除。</p>
<p>有时候我们撤销不一定就非要删表,我们可能会有其他动作,这个时候我们就可以通过手动修改迁移脚本中的<code>down函数</code>代码来实现自定义撤销操作。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122110705-38435349.png" alt="1607744130113" loading="lazy"></p>
<p>另外我们还可以通过<code>db:migrate:undo:all</code>命令来撤销所有的迁移脚本。</p>
<p>通过<code>db:migrate:undo --name 脚本名</code>命令指定撤销具体的迁移脚本。</p>
<pre><code class="language-shell">sequelize-cli db:migrate:undo 20201212030431-create-message.js
</code></pre>
<p>那么如何迁移单个指定的文件呢?一般情况下我们要迁移的文件都应该是放在一个单独的文件夹下面的,然后通过下面命令指定迁移目录即可。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122110880-1193632894.png" alt="1607745692178" loading="lazy"></p>
<h2 id="在表中添加字段">在表中添加字段</h2>
<p>如何在不影响表原有的情况下添加新的字段?例如我们给users表中增加一个age字段。</p>
<p>创建迁移文件。</p>
<pre><code class="language-shell">sequelize-cli migration:create --name UserAddAge
</code></pre>
<p>创建之后找到迁移脚本文件,然后在up和down中增加如下代码。</p>
<pre><code class="language-js">'use strict';

module.exports = {
up: async (queryInterface, Sequelize) =&gt; {
    /**
   * Add altering commands here.
   *
   * Example:
   * await queryInterface.createTable('users', { id: Sequelize.INTEGER });
   */
    await queryInterface.addColumn(
      'users',
      'age', {
      type: Sequelize.TINYINT
      }
    )
},

down: async (queryInterface, Sequelize) =&gt; {
    /**
   * Add reverting commands here.
   *
   * Example:
   * await queryInterface.dropTable('users');
   */
    await queryInterface.removeColumn(
      'users',
      'age'
    )
}
};
</code></pre>
<p>addColumn这个API的第一个参数是你要添加列的表名,age是添加的字段,type是数据类型。</p>
<p>removeColumn这个API是删除列。</p>
<p>添加代码之后再执行<code>db:migrate</code>命令发现已经有了age字段了。</p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122111023-1944956207.png" alt="1607775853301" loading="lazy"></p>
<p>如果我们撤销的话,也不会影响原有的users表结构,只会把users表中的age字段删除。</p>
<p>撤销最近一次迁移:<code>db:migrate:undo</code></p>
<h2 id="种子文件seeder">种子文件seeder</h2>
<p>比如往表里面添加测试数据的时候我们就可以使用种子文件来实现。</p>
<h3 id="创建种子文件">创建种子文件</h3>
<p>命令:<code>sequelize-cli seed:create --name userTest</code></p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122111305-1365151035.png" alt="1607776268462" loading="lazy"></p>
<h3 id="添加测试数据">添加测试数据</h3>
<pre><code class="language-js">'use strict';

module.exports = {
up: async (queryInterface, Sequelize) =&gt; {
    /**
   * Add seed commands here.
   *
   * Example:
   * await queryInterface.bulkInsert('People', [{
   *   name: 'John Doe',
   *   isBetaMember: false
   * }], {});
    */
    await queryInterface.bulkInsert('users', [
      {
      username: '张三',
      age: 20
      },
      {
      username: '李四',
      age: 21
      }
    ])
},

down: async (queryInterface, Sequelize) =&gt; {
    /**
   * Add commands to revert seed here.
   *
   * Example:
   * await queryInterface.bulkDelete('People', null, {});
   */
    await queryInterface.bulkDelete('users', null, {});
}
};
</code></pre>
<p>up函数里面的<code>bulkInsert</code>API第一个参数是要操作的表名,第二个参数是要插入的数据,是一个数组对象的格式。</p>
<p>down函数里面的<code>bulkDelete</code>API是用来删除数据的,这里是将users表的数据清空。</p>
<h3 id="运行种子文件">运行种子文件</h3>
<p>命令:<code>sequelize-cli db:seed:all</code></p>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122111579-1294884534.png" alt="1607776758906" loading="lazy"></p>
<ul>
<li>指定运行种子文件:<code>db:seed 种子文件</code></li>
<li>运行所有种子文件:<code>db:seed:all</code></li>
</ul>
<h3 id="撤销种子文件">撤销种子文件</h3>
<p>命令:<code>sequelize-cli db:seed:undo</code></p>
<ul>
<li>指定撤销种子文件:<code>db:seed:undo 种子文件</code></li>
<li>撤销所有种子文件:<code>db:seed:undo:all</code></li>
</ul>
<p>如果哪天测试数据被我玩坏了,用这个命令就可以很方便的还原。</p>
<p>种子文件添加、撤销默认没有进行记录,因此我们需要手动添加记录,方便以后查看、溯源。</p>
<p>官方文档告诉我们需要在<code>config/config.json</code>配置文件中添加配置。</p>
<p>通过JSON的方式存储。</p>
<pre><code class="language-json">"development": {
    "username": "root",
    "password": "root",
    "database": "c4az6_development",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "seederStorage": "json",
    "seederStoragePath": "userTestDataLog.json"
}
</code></pre>
<p>通过数据库存储。</p>
<pre><code class="language-json">"development": {
    "username": "root",
    "password": "root",
    "database": "c4az6_development",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "seederStorage": "sequelize",
    "seederStorageTableName": "userTestDataLog"
},
</code></pre>
<p><img src="https://img2020.cnblogs.com/blog/2217722/202012/2217722-20201219122111719-433376817.png" alt="1607778464267" loading="lazy"></p>
<blockquote>
<p>注意:migration迁移的记录默认使用数据库存储,seeder种子文件生成的记录默认是没有存储的,需要手动在config/config.json中配置,要么使用JSON文件方式并且配置存储路径进行存储,要么使用数据库的方式存储。</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/alexander3714/p/14158613.html
頁: [1]
查看完整版本: 玩转Node.js-Sequelize数据迁移