Node.js 在模型和迁移之间复制数据

Node.js 在模型和迁移之间复制数据,node.js,sequelize.js,Node.js,Sequelize.js,我正在学习Sequelize,我发现有些东西很奇怪,所以我认为我做错了什么 这是我对一个简单的Posts表的迁移: 'use strict'; module.exports = { up: (queryInterface, Sequelize) => { return queryInterface.createTable('Posts', { id: { allowNull: false,

我正在学习Sequelize,我发现有些东西很奇怪,所以我认为我做错了什么

这是我对一个简单的
Posts
表的迁移:

'use strict';
module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.createTable('Posts', {
            id: {
                allowNull: false,
                autoIncrement: true,
                primaryKey: true,
                type: Sequelize.INTEGER
            },
            title: {
                type: Sequelize.STRING,
                allowNull: false,
            },
            content: {
                type: Sequelize.TEXT,
                allowNull: false,
            },
            authorId: {
                type: Sequelize.INTEGER,
                onDelete: 'CASCADE',
                allowNull: false,
                references: {model: 'Users', key: 'id'}
            },
            publishedAt: {
                type: Sequelize.DATE,
                allowNull: true
            },
            createdAt: {
                allowNull: false,
                type: Sequelize.DATE
            },
            updatedAt: {
                allowNull: false,
                type: Sequelize.DATE
            }
        });
    },
    down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable('Posts');
    }
};
这里还有一个小问题,如果不希望标题和内容为空,是否必须为标题和内容指定
allowNull:false
。我想是的,但我看到的许多项目都没有具体说明

这是
Post
模型:

'use strict';
module.exports = (sequelize, DataTypes) => {
    const Post = sequelize.define('Post', {
        id: {
            allowNull: false,
            autoIncrement: true,
            primaryKey: true,
            type: DataTypes.INTEGER
        },
        title: {
            type: DataTypes.STRING,
            allowNull: false,
        },
        content: {
            type: DataTypes.TEXT,
            allowNull: false,
        },
        publishedAt: {
            type: DataTypes.DATE,
            allowNull: true
        },
    }, {
        classMethods: {
            associate: function (models) {
                Post.belongsTo(models.User, {
                    onDelete: 'CASCADE',
                    foreignKey: {
                        fieldName: 'authorId',
                        allowNull: false
                    }
                });
            }
        }
    });

    return Post;
};

我在两个文件之间重复了相同的数据。。。我来自Laravel,所以在NodeJS世界中,这样做可能是很常见的。

是的,目前您必须将字段定义从模型复制到相应的迁移,这对于构建应用程序来说确实不是一个好方法

然而,有一个包可以自动从您的模型生成迁移,您可以在这里检查它:但它是否处于早期阶段

您也可以在此处阅读关于同一主题的讨论:

  • 如果您希望数据不为
    null
    ,最好添加DB约束,即使它不是强制性的,您也可以在代码中强制执行

  • 关于你的第二个问题,简短的回答是肯定的。在您的情况下,您正在复制代码。但很有可能您将来会添加或修改表模式,这将导致您的模型看起来与第一个迁移文件不同。请记住,迁移文件在生产环境中运行后不会更改,因为它只运行一次。任何时候您想要更改您的表模式,您都必须创建一个新的迁移文件

  • 我也想帮助未来的游客

    @Wizix,allowNull对于避免数据库中的空输入非常重要。它是服务器端的验证

    示例

    const User = db.define('users', {
      fullname: {
        type: Sequelize.STRING(50),
        allowNull: false,
        validate: {
          notEmpty: {
            args: true,
            msg: 'Please provide fullname',
          },
        },
      }
    })
    
    我希望用户输入不是空的

      allowNull in models validate input before processed to a database
    
      allowNull in migration is the last checking validation where we decide to save to a database or to reject the user input.
    
    重复数据
    我发现有必要让这两个条件都验证输入。

    为了避免模型和迁移之间的代码重复,请在迁移中使用模型,如下所示:

    'use strict';
    const { User } = require('../models');
    module.exports = {
        up: (queryInterface, Sequelize) => {
            return User.sync();
            // return queryInterface.createTable('user', { id: Sequelize.INTEGER });
        },
    
        down: (queryInterface, Sequelize) => {
            return queryInterface.dropTable('user');
        }
    };
    

    编辑:

    这是一个很好的选项,仅用于添加新表

    注意“{alter:true}”!更改现有列时,请注意sequelize可能无法识别列重命名,并将执行两个“删除”和“添加”操作,而不仅仅是一个“更改”。 因此,为了更新模式,最好使用
    queryInterface.renameColumn
    queryInterface.changeColumn
    或原始查询


    问题是什么?如果所有内容都已在模型中,那么迁移的效用是什么?来自sequelize docs:“不建议用于生产。如果未进一步配置,将删除模型中已删除或其类型已更改的列中的数据。”