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

Database Sequelize.js:如何使用迁移和同步,database,node.js,database-migration,sequelize.js,Database,Node.js,Database Migration,Sequelize.js,我的项目即将启动。在发布之后,我有一个很大的计划,数据库结构将发生变化——现有表和新表中的新列,以及与现有模型和新模型的新关联 在Sequelize中,我还没有涉及迁移,因为我只有测试数据,我不介意每次数据库更改时都删除这些数据 为此,目前,如果我更改了模型定义,我会在我的应用程序启动时运行sync force:true。这将删除所有表并从头开始创建它们。我可以省略force选项,让它只创建新表。但如果现有的改变了,这是没有用的 那么,一旦我加入了迁移,事情是如何运作的呢?显然,我不希望删除现有

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

在Sequelize中,我还没有涉及迁移,因为我只有测试数据,我不介意每次数据库更改时都删除这些数据

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

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

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

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

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

我一定错过了什么


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

我只是自学了这一点,但我想我建议您现在就使用迁移,以便您习惯它们。我发现要弄清楚迁移过程中发生了什么,最好的办法是查看由
sequelize.sync()
创建的表上的sql,然后从中构建迁移

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

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

migration.dropTable('MyTable');
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'
    ]
  ]
但是对表结构的后续更新可以忽略这一点,只需使用ALTERTABLE即可

./node_modules/.bin/sequelize --migrate
创建示例如下所示:

migration.dropTable('MyTable');
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'
    ]
  ]
从头开始重做:

migration.dropTable('MyTable');
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'
    ]
  ]
我正在使用coffee运行一个种子文件来填充以下表格:

migration.dropTable('MyTable');
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'
    ]
  ]
它只是有一个create函数,看起来像:

migration.dropTable('MyTable');
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()
从模型的索引中删除,否则它将覆盖迁移和种子所做的操作

当然,医生们都很忙。但基本的答案是,你必须自己添加所有内容来指定你需要的字段。它不适合您。

使用版本。 应用程序的版本取决于数据库的版本。 如果新版本需要更新数据库,请为其创建迁移


更新:我决定放弃迁移()并在需要时运行script update_db(sync forse:false)。

有点晚了,在阅读文档之后,您不需要进行您所说的第一次迁移。您只需调用
sync
即可创建表

sequelize.sync()

您还可以通过执行以下操作来运行简单的模型同步:

Project.sync()
但是我认为
sequelize.sync()
对于您的项目来说是一个更有用的通用案例(只要您在开始时导入好的模型)

(摘自)

这将创建所有初始结构。之后,您只需创建迁移就可以改进模式


希望有帮助。

Sequelize可以异步运行任意SQL

我要做的是:

  • 生成迁移(用作第一次迁移)
  • 转储数据库,类似于:
    mysql\u Dump-uUSER-pPASS DBNAME>FILE.SQL
  • 或者将整个转储粘贴为tex