如何使用 Sequelize 在迁移中添加对另一个表列作为外键的引用

Jak*_*kub 1 postgresql node.js sequelize.js

在我的 Node API 中,我使用 ORM Sequuilize 并尝试了解如何以这种方式使迁移文件通过外键相互引用到表。

我有一个学生,他有很多项目,并且项目属于一个学生。

所以我的模型是这样的:

module.exports = (sequelize, DataTypes) => {
    const Student = sequelize.define("Student", {
        _id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            //autoIncrement: true
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false
        },
        email: {
            type: DataTypes.TEXT,
            allowNull: false,
            unique: true
        },
        dateOfBirth: {
            type: DataTypes.DATEONLY,
            allowNull: false
        },
        createdAt: {
            type: DataTypes.DATE,
            allowNull: false
        },
        updatedAt: {
            type: DataTypes.DATE,
            allowNull: false
        }
    });

    Student.associate = function(models) {
        Student.hasMany(models.Project, {
            foreignKey: 'student_id',
            as: 'projects',
            onDelete: 'CASCADE',
          });
    };
    return Student;
};
Run Code Online (Sandbox Code Playgroud)

项目型号:

module.exports = (sequelize, DataTypes) => {
    const Project = sequelize.define("Project", {
        project_id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            //autoIncrement: true
        },
        student_id: {
            type: DataTypes.UUIDV4,
            allowNull: false,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false,
            unique: true
        },
        description: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        creationDate: {
            type: DataTypes.DATEONLY,
            allowNull: true
        },
        repoUrl: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        liveUrl: {
            type: DataTypes.TEXT,
            allowNull: true
        },
        createdAt: {
            type: DataTypes.DATE,
            allowNull: false
        },
        updatedAt: {
            type: DataTypes.DATE,
            allowNull: false
        }
    });

    Student.associate = function(models) {
        Project.belongsTo(models.Student, {
            foreignKey: "student_id",
            as: "student",
            onDelete: "CASCADE"
        });
    };
    return Student;
};
Run Code Online (Sandbox Code Playgroud)

我的迁移如下,但正如我之前所说,我不知道如何包含外键,而且我的方式不起作用,迁移已创建,但在数据库中未建立关系:

学生移民

"use strict";

module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.createTable("Students", {
            _id: {
                primaryKey: true,
                type: Sequelize.UUID,
                defaultValue: Sequelize.UUIDV4,
                //autoIncrement: true
            },
            name: {
                type: Sequelize.STRING,
                allowNull: false
            },
            email: {
                type: Sequelize.TEXT,
                allowNull: false,
                unique: true
            },
            dateOfBirth: {
                type: Sequelize.DATEONLY,
                allowNull: false
            },
            createdAt: {
                type: Sequelize.DATE,
                allowNull: false
            },
            updatedAt: {
                type: Sequelize.DATE,
                allowNull: false
            }
        });
    },

    down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable("Students");
    }
};
Run Code Online (Sandbox Code Playgroud)

项目迁移

"use strict";

module.exports = {
    up: (queryInterface, Sequelize) => {
        return queryInterface.createTable("Projects", {
            project_id: {
                primaryKey: true,
                type: Sequelize.UUID,
                defaultValue: Sequelize.UUIDV4
                //autoIncrement: true
            },
            student_id: {
                foreignKey: true,
                type: Sequelize.UUID,
                defaultValue: Sequelize.UUIDV4,
                allowNull: false
            },
            name: {
                type: Sequelize.STRING,
                allowNull: false,
                unique: true
            },
            description: {
                type: Sequelize.TEXT,
                allowNull: true
            },
            creationDate: {
                type: Sequelize.DATEONLY,
                allowNull: true
            },
            repoUrl: {
                type: Sequelize.TEXT,
                allowNull: true
            },
            liveUrl: {
                type: Sequelize.TEXT,
                allowNull: true
            },
            createdAt: {
                type: Sequelize.DATE,
                allowNull: false
            },
            updatedAt: {
                type: Sequelize.DATE,
                allowNull: false
            }
        });
    },

    down: (queryInterface, Sequelize) => {
        return queryInterface.dropTable("Projects");
    }
};
Run Code Online (Sandbox Code Playgroud)

sli*_*wp2 5

以下是迁移工作流程:

  1. 使用 生成模型和迁移文件sequelize-cli
  2. Student根据您的业务需求定义之间的关联Project
  3. 根据模型之间的关联,修改迁移文件,添加外键(student_idProject表添加列)。对于您的情况,Project表有一列作为对表列的student_id外键引用。Student_id

这是工作示例:

models/student.js:

module.exports = (sequelize, DataTypes) => {
  const Student = sequelize.define('Student', {
    _id: {
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    email: {
      type: DataTypes.TEXT,
      allowNull: false,
      unique: true,
    },
    dateOfBirth: {
      type: DataTypes.DATEONLY,
      allowNull: false,
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
    },
  });

  Student.associate = function(models) {
    Student.hasMany(models.Project, {
      foreignKey: 'student_id',
      as: 'projects',
    });
  };
  return Student;
};
Run Code Online (Sandbox Code Playgroud)

models/project.js:

module.exports = (sequelize, DataTypes) => {
  const Project = sequelize.define('Project', {
    project_id: {
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
    },
    description: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    creationDate: {
      type: DataTypes.DATEONLY,
      allowNull: true,
    },
    repoUrl: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    liveUrl: {
      type: DataTypes.TEXT,
      allowNull: true,
    },
    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
    },
    updatedAt: {
      type: DataTypes.DATE,
      allowNull: false,
    },
  });

  Project.associate = function(models) {
    Project.belongsTo(models.Student, {
      foreignKey: 'student_id',
      as: 'student',
      onDelete: 'CASCADE',
    });
  };
  return Project;
};
Run Code Online (Sandbox Code Playgroud)

migrations/20200213113039-create-student.js:

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Students', {
      _id: {
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      email: {
        type: Sequelize.TEXT,
        allowNull: false,
        unique: true,
      },
      dateOfBirth: {
        type: Sequelize.DATEONLY,
        allowNull: false,
      },
      createdAt: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updatedAt: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });
  },

  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Students');
  },
};
Run Code Online (Sandbox Code Playgroud)

migrations/20200213113231-create-project.js:

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Projects', {
      project_id: {
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
      },
      student_id: {
        type: Sequelize.UUID,
        references: {
          model: {
            tableName: 'Students',
          },
          key: '_id',
        },
        allowNull: false,
        onDelete: 'CASCADE',
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
        unique: true,
      },
      description: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      creationDate: {
        type: Sequelize.DATEONLY,
        allowNull: true,
      },
      repoUrl: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      liveUrl: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      createdAt: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updatedAt: {
        type: Sequelize.DATE,
        allowNull: false,
      },
    });
  },

  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Projects');
  },
};
Run Code Online (Sandbox Code Playgroud)

执行命令后npx sequelize-cli db:migrate,查看数据库中的表信息(我还创建了种子文件来插入一些演示数据):

node-sequelize-examples=# select * from "Students";
                 _id                  |     name      |          email           | dateOfBirth |           createdAt           |           updatedAt
--------------------------------------+---------------+--------------------------+-------------+-------------------------------+-------------------------------
 2c6db3cb-82c7-4728-a259-23520bd760d0 | Rosalind Mohr | Natasha.Littel@gmail.com | 2020-02-13  | 2020-02-13 12:39:23.508379+00 | 2020-02-13 12:39:23.508379+00
(1 row)

node-sequelize-examples=# select * from "Projects";
              project_id              | name  | description | creationDate | repoUrl | liveUrl |           createdAt           |           updatedAt           |              student_id
--------------------------------------+-------+-------------+--------------+---------+---------+-------------------------------+-------------------------------+--------------------------------------
 b271060c-bd20-48f4-a8a5-65508b99cfbf | nobis |             |              |         |         | 2020-02-13 12:39:23.540054+00 | 2020-02-13 12:39:23.540054+00 | 2c6db3cb-82c7-4728-a259-23520bd760d0
(1 row)
Run Code Online (Sandbox Code Playgroud)

描述一下表格:

node-sequelize-examples=# \d "Students";
              Table "public.Students"
   Column    |           Type           | Modifiers
-------------+--------------------------+-----------
 _id         | uuid                     | not null
 name        | character varying(255)   | not null
 email       | text                     | not null
 dateOfBirth | date                     | not null
 createdAt   | timestamp with time zone | not null
 updatedAt   | timestamp with time zone | not null
Indexes:
    "Students_pkey" PRIMARY KEY, btree (_id)
    "Students_email_key" UNIQUE CONSTRAINT, btree (email)
Referenced by:
    TABLE ""Projects"" CONSTRAINT "Projects_student_id_fkey" FOREIGN KEY (student_id) REFERENCES "Students"(_id) ON UPDATE CASCADE ON DELETE CASCADE

node-sequelize-examples=# \d "Projects";
               Table "public.Projects"
    Column    |           Type           | Modifiers
--------------+--------------------------+-----------
 project_id   | uuid                     | not null
 name         | character varying(255)   | not null
 description  | text                     |
 creationDate | date                     |
 repoUrl      | text                     |
 liveUrl      | text                     |
 createdAt    | timestamp with time zone | not null
 updatedAt    | timestamp with time zone | not null
 student_id   | uuid                     |
Indexes:
    "Projects_pkey" PRIMARY KEY, btree (project_id)
    "Projects_name_key" UNIQUE CONSTRAINT, btree (name)
Foreign-key constraints:
    "Projects_student_id_fkey" FOREIGN KEY (student_id) REFERENCES "Students"(_id) ON UPDATE CASCADE ON DELETE CASCADE
Run Code Online (Sandbox Code Playgroud)

我相信您希望在删除用户时删除该用户的所有项目。