当前位置: 首页 > 知识库问答 >
问题:

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

东门城
2023-03-14

我的项目即将启动。在发布之后,我有一个很大的计划,数据库结构将发生变化——现有表和新表中的新列,以及与现有模型和新模型的新关联。

我还没有接触到序列化中的迁移,因为我只有测试数据,我不介意每次数据库更改时都删除这些数据。

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

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

如何在Sequelize中生成这样的“第一次迁移”?如果我没有,那么应用程序的一个新实例可能没有框架数据库来运行迁移,或者它将在开始时运行sync,并使数据库与所有新表等一起处于新状态,但当它尝试运行迁移时,它们就没有意义了,因为它们是在考虑原始数据库和每个后续迭代的情况下编写的。

我的思考过程:在每个阶段,初始数据库加上每次迁移的顺序应该等于运行sync force: true时生成的数据库(加减数据)。这是因为代码中的模型描述描述了数据库结构。因此,如果没有迁移表,我们只需运行sync并将所有迁移标记为已完成,即使它们没有运行。这是我需要做的吗(怎么做?),还是Sequelize应该自己做这件事,还是我找错人了?如果我在正确的区域,考虑到旧的模型(通过提交哈希?或者甚至每个迁移都可以绑定到一个提交?我承认我是在一个非便携式git中心的世界里思考)和新的模型。它可以区分结构,并生成将数据库从旧数据库转换为新数据库所需的命令,然后开发人员可以进行任何必要的调整(删除/转换特定数据等)。

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

我一定错过了什么。

TLDR:如何设置我的应用程序及其迁移,以使live应用程序的各种实例都可以更新,以及一个没有遗留启动数据库的全新应用程序?

共有3个答案

林彬
2023-03-14

对于开发,现在可以通过改变当前表的结构来同步它们。使用sequelize github repo的最新版本,现在可以使用alter参数运行同步。

Table.sync({alter: true})

医生的警告:

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

乐正意智
2023-03-14

我自己也在学习这个,但是我想我建议现在使用迁移,这样你就会习惯它们。我发现弄清楚迁移过程中发生了什么的最好方法是查看由sequelize.sync()创建的表上的sql,然后从那里构建迁移。

migrations -c [migration name] 

将在迁移目录中创建模板迁移文件。然后,您可以使用需要创建的字段填充它。此文件需要包括createdAt/updatedAt、关联所需的字段等。

对于初始表创建,向下应具有:

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

我使用咖啡运行一个种子文件来填充表后:

coffee server/seed.coffee

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

user = db.User.create
  username: 'bob'
  password: 'suruncle'
  email: 'bob@bob.com'
.success (user) ->
  console.log 'added user'
  user_id = user.id
  myTable = [
    field1: 'womp'
    field2: 'rat'

    subModel: [
      field1: 'womp'
     ,
      field1: 'rat'
    ]
  ]

请记住将你的sync()从模型中的索引中删除,否则它将覆盖迁移和种子所做的事情。

文档位于http://sequelize.readthedocs.org/en/latest/docs/migrations/当然但基本的答案是,你必须自己添加所有内容来指定你需要的字段。它不适合你。

翟嘉祥
2023-03-14

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

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

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

sequelize db:migrate

这将创建一个将要迁移的模式。您应该只执行一次,以切换到正确的模式开发过程(不使用sync:force,但使用权威迁移)。

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

  1. 创建迁移:续集迁移:创建
  2. 在迁移文件中写入上下函数
  3. 根据迁移文件中的更改,手动更改模型
  4. 运行sequelize db:migrate

显然,您不能ssh正式服用手运行迁移。使用umzug,节点的框架无关迁移工具。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
    });
});

我现在不能试试这个,但乍一看应该行得通。

一年后,仍然有用,所以分享我目前的技巧。现在,我正在安装测序-cli包作为所需的live依赖项,然后在package.json中修改NPM启动脚本,如下所示:

...
"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。

 类似资料:
  • 问题内容: MyBatis迁移将每个SQL文件分为两部分: 一种用于向前迁移一个版本 一种用于迁移回一个版本 如何使用Flyway回滚版本? 问题答案: 尽管Flyway支持回滚(仅作为商业功能),但不鼓励使用它: https://flywaydb.org/documentation/command/undo 尽管撤消迁移的想法很好,但不幸的是,有时它在实践中会崩溃。一旦您进行了破坏性的更改(删除

  • 我有这段HTML代码。我想去一个兄弟节点。我按标题进行搜索(因为这是UI中唯一的值),但我想移动到相同的级别,但使用不同的类名,它将包含ant-select-tree-switcher_close。 这是标记内容的xpath,我只想在第一个span的同一级别中移动,但不包括span1或任何硬编码的解决方案。我想通过类名搜索包含单词ant-select-tree-switcher_close作为类名

  • 我买了新的MacBook Pro,我在其中安装了mysql,然后安装sequel Pro来查看表和数据库,但是当我命令时,这个错误指控错误图像 近30个小时来,我一直在忍受这个问题,有人能帮我看一下吗

  • 问题内容: 我正在使用CakePHP v3.x,并且试图弄清楚如何通过迁移工具插入一些记录。该文档仅列出了用于修改架构的方法。我是否需要使用原始SQL手动插入记录? 问题答案: CakePHP 3的Migration插件是Phinx包装器插件,因此可以使用以下方法添加记录: 例如,你可以使用添加新用户上: - 如果使用,请不要忘了在迁移文件的顶部添加。 对于CakeDC的Migration插件,您

  • 在某些库上运行Jetifier时,错误消息如下所示(针对多个用户不断弹出一个特定的库:): 这个问题已经在Jetifier工具本身修复了一段时间,但修复版本还没有包含在任何Android Studio更新中(即使是最新的金丝雀版本)。 > 在每个库上运行独立工具,并指示Gradle使用这些版本(我可能需要告诉Gradle任务不要在它们上运行Jetifier) 指导Gradle任务使用独立工具来代替