Sequelize.js:如何使用迁移和同步

 我叫yyson_836 发布于 2023-02-03 09:28

我已准备好启动我的项目了.我有很大的计划在发布后,数据库结构将发生变化 - 现有表中的新列以及新表,以及与现有模型和新模型的新关联.

我还没有触及Sequelize中的迁移,因为我只有测试数据,我不介意每次数据库更改时擦除.

为此,目前我正在运行sync force: true应用程序启动时,如果我更改了模型定义.这会删除所有表并从头开始创建它们.我可以省略force让它只创建新表的选项.但如果现有的已经改变,这没有用.

所以,一旦我添加了迁移,事情是如何运作的?显然,我不希望现有的表(包含其中的数据)被消灭,因此sync force: true是不可能的.在我帮助开发的其他应用程序(Laravel和其他框架)作为应用程序部署过程的一部分,我们运行migrate命令来运行任何挂起的迁移.但是在这些应用程序中,第一次迁移有一个骨架数据库,数据库处于开发初期的状态 - 第一个alpha版本或其他任何版本.因此,通过按顺序运行所有迁移,即使是派对迟到的应用程序实例也可以一次性加快速度.

如何在Sequelize中生成这样的"第一次迁移"?如果我没有,那么应用程序的某个新实例将在没有框架数据库的情况下运行迁移,或者它将在开始时运行同步并将使数据库处于新状态新表等,但是当它尝试运行迁移时,它们将没有意义,因为它们是用原始数据库编写的,并且每次连续迭代都在考虑之中.

我的思考过程:在每个阶段,初始数据库加上每个顺序的迁移应该等于(加或减数据)sync force: true运行时生成的数据库.这是因为代码中的模型描述描述了数据库结构.因此,如果没有迁移表,我们只需运行同步并将所有迁移标记为已完成,即使它们未运行.这是我需要做的(怎么样?),或者Sequelize本身应该这样做,还是我咆哮着错误的树?如果我在正确的区域,肯定应该有一个很好的方法来自动生成大部分迁移,给定旧模型(通过提交哈希?甚至每次迁移都可以绑定到提交?我承认我在想在一个非便携式的以git为中心的宇宙中)和新模型.它可以区分结构并生成将数据库从旧变换到新变换所需的命令,然后开发人员可以进入并进行任何必要的调整(删除/转换特定数据等).

当我使用--init命令运行sequelize二进制文件时,它会给我一个空的迁移目录.当我运行sequelize --migrate它时,它使我成为SequelizeMeta表,其中没有任何内容,没有其他表.显然不是,因为二进制文件不知道如何引导我的应用程序并加载模型.

我肯定错过了什么.

TLDR:如何设置我的应用程序及其迁移,以便更新实时应用程序的各种实例,以及没有旧版启动数据库的全新应用程序?

3 个回答
  • 只是自己学习,但我想我会建议现在使用迁移,以便你习惯它们.我发现最好的办法是弄清楚迁移中的内容是查看sequelize.sync()创建的表上的sql,然后从那里构建迁移.

    迁移-c [迁移名称]

    将在迁移目录中创建模板迁移文件.然后,您可以使用您需要创建的字段填充它.此文件需要包含createdAt/updatedAt,关联所需的字段等.对于初始表创建,应该具有:

    migration.dropTable( 'MyTable的');

    但是对表结构的后续更新可以将其保留,只使用alter table.

    migrations -c [migration name] 
    

    一个示例创建如下:

    migration.dropTable('MyTable');
    

    从头开始重做:

    ./node_modules/.bin/sequelize --migrate
    

    我正在使用咖啡运行种子文件来填充表格:

    module.exports = {
      up: function(migration, DataTypes, done) {
        migration.createTable(
            'MyTable',
            {
              id: {
                type: DataTypes.INTEGER,
                primaryKey: true,
                autoIncrement: true
              },
              bigString: {type: DataTypes.TEXT, allowNull: false},
              MyOtherTableId: DataTypes.INTEGER,
              createdAt: {
                type: DataTypes.DATE
              },
              updatedAt: {
                type: DataTypes.DATE
              }
            });
        done();
      },
      down: function(migration, DataTypes, done) {
        migration.dropTable('MyTable');
        done();
      }
    

    这只是一个创建函数,看起来像:

    ./node_modules/.bin/sequelize --migrate --undo
    ./node_modules/.bin/sequelize --migrate
    

    请记住在模型中将sync()从索引中删除,否则它将覆盖迁移和种子执行的操作.

    Docs 当然是http://sequelize.readthedocs.org/en/latest/docs/migrations/.但基本的答案是你必须自己添加一切来指定你需要的字段.它不适合你:-(

    2023-02-03 09:33 回答
  • 生成"第一次迁移"

    在您的情况下,最可靠的方法是几乎手动完成.我建议使用sequelize-cli工具.语法很简单:

    sequelize init
    ...
    sequelize model:create --name User --attributes first_name:string,last_name:string,bio:text
    

    这将创建模型和迁移.然后,使用sequelize-cli手动合并现有模型,并对迁移执行相同操作.执行此操作后,擦除数据库(如果可能),然后运行

    sequelize db:migrate
    

    这将创建架构将迁移.您应该只执行一次以切换到正确的模式开发过程(不同步:强制,但具有权威性迁移).

    以后,当您需要更改架构时:

      创建迁移: sequelize migration:create

      在迁移文件中写入向上和向下功能

      根据您在迁移文件中的更改,手动更改模型

      sequelize db:migrate

    在生产上运行迁移

    显然,你不能ssh到生产服务器并手动运行迁移.使用umzug,框架无关的迁移工具,Node.JS在应用程序启动之前执行挂起的迁移.

    您可以获得一个待处理/尚未执行的迁移列表,如下所示:

    umzug.pending().then(function (migrations) {
      // "migrations" will be an Array with the names of
      // pending migrations.
    }); 
    

    然后执行迁移(内部回调).execute方法是一个通用函数,它为每个指定的迁移运行相应的函数:

    umzug.execute({
      migrations: ['some-id', 'some-other-id'],
      method: 'up'
    }).then(function (migrations) {
      // "migrations" will be an Array of all executed/reverted migrations.
    });
    

    我的建议是在应用程序启动之前执行此操作并尝试每次都提供路由.像这样的东西:

    umzug.pending().then(function(migrations) {
        // "migrations" will be an Array with the names of
        // pending migrations.
        umzug.execute({
            migrations: migrations,
            method: 'up'
        }).then(function(migrations) {
            // "migrations" will be an Array of all executed/reverted migrations.
            // start the server
            app.listen(3000);
            // do your stuff
        });
    });
    

    我现在不能尝试这个,但首先看它应该有效.

    UPD 2016年4月

    一年后,仍然有用,所以分享我目前的提示.现在,我安装sequelize-cli包为需要现场扶养,然后修改NPM启动脚本package.json是这样的:

    ...
    "scripts": {
      "dev": "grunt && sequelize db:migrate && sequelize db:seed:all && node bin/www",
      "start": "sequelize db:migrate && sequelize db:seed:all && node bin/www"
    },
    ...
    

    我在生产服务器上唯一需要做的就是npm start.此命令将运行所有迁移,应用所有播种器并启动应用服务器.无需手动调用umzug.

    2023-02-03 09:34 回答
  • 对于开发,现在有一个选项可以通过改变它们的结构来同步当前表.使用sequelize github repo中的最新版本,您现在可以使用alter参数运行sync .

    Table.sync({alter: true})
    

    来自文档的警告:

    改变表格以适合模型.不建议用于生产用途.删除已删除的列中的数据或在模型中更改其类型的数据.

    2023-02-03 09:34 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有