javascript - 如何使用 sequelize.js 将表的列设置为外键

标签 javascript node.js foreign-keys mariadb sequelize.js

我想要实现的是:当添加新的比赛时,我需要在表 team_comp 中创建一行,其中包含表 Competition 的字段“competition_teams”的相同 ID 和我发送的额外数据按要求。我会有很多比赛,但每场比赛都有一个属于它的 team_comp。如果我删除一个比赛,它的 team_comp 行必须被删除。
竞争 :

| id  | name  | competition_teams |
|  1  |  A    |      32           |
team_comp 表:
| id  | competition_id  | test_h |
|  3  |       32        |  1     |
在我的 models/index.js 我定义了这样的关联:
// Competition
db.competition.hasOne(db.competition_team, {as: 'compId', foreignKey : 'competition_id'});

// Competition Teams
db.competition_team.belongsTo(db.competition, {as: 'compTeam', foreignKey : 'competition_id', onDelete: 'CASCADE'});
通过这样做,我得到了错误的外键。它在表 ** team_comp ** 中创建了一个外键,指向 competion.id 而不是 Competition.competition_teams (这是我想要的)。
我怎样才能让它指向competition.competition_teams?
这是我添加新比赛的方式(controllers/competition.js):
import db from '../models/index';
const Competition = db.competition;
const Competition_teams = db.competition_team;

// create competition
const create = (req, res) => {

    // generating a random id for the competition
    var competition_teams = Math.floor(Math.random() * 100);

    let { 
       name, 
       test_h,
    } = req.body;
     
    // create new Competition
    let newCompetition = { 
      name, 
      competition_teams // this must be also added in table team_comp, column competition_id
    }

    let newCompetitionTeams = {
      test_h
    }

    Competition.create(newCompetition)
      .then(Competition => {
        res.json({ Competition });
      })
      .catch(err => {
        console.log("Error: " + err);
        return res.status(500).json({ err });
      });

    // creating teams association    
    Competition_teams.create(newCompetitionTeams)
      .then(Competition_teams => {
        res.json({ Competition_teams });
      })
      .catch(err => {
        console.log("Error: " + err);
        return res.status(500).json({ err });
      });
}

最佳答案

您需要在关联中指定 sourceKey 属性 - 如果忽略它将使用 table + id Reference

The name of the attribute to use as the key for the association in the source table. Defaults to the primary key of the source table


请参阅以下完整示例:
class Competition extends Sequelize.Model {
}

Competition.init({
    id: {
        primaryKey: true,
        type: Sequelize.INTEGER,
        allowNull: false
    },
    name: {
        type: Sequelize.STRING(36)
    },
    team_competition_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
    }
}, {
    sequelize,
    modelName: 'competition',
    tableName: 'competitions',
    timestamps: false
});

class Team_Competition extends Sequelize.Model {
}

Team_Competition.init({
    id: {
        primaryKey: true,
        type: Sequelize.INTEGER,
        allowNull: false
    },
    name: {
        type: Sequelize.STRING(36)
    },
}, {
    sequelize,
    modelName: 'team_competition',
    tableName: 'team_competitions',
    timestamps: false
});

// use sourceKey here - also make sure you specify `cascade` and `hooks` property
Competition.hasOne(Team_Competition, {sourceKey: 'team_competition_id', foreignKey: 'id', onDelete: 'cascade', hooks: true});

// tests
    // create the team_competition
    const team_competition = await Team_Competition.create({
        id: 1,
        name: 'Team A'
    });

    // create the competition
    const competition = await Competition.create({
        id: 1,
        name: 'Comp A',
        team_competition_id: team_competition.id
    });

    // test the join
    const competitions = await Competition.findAll({
        include: [
            {
                attributes: ['id', 'name'],
                model: Team_Competition,
            }
        ],
        raw: true
    });

    // delete and verify cascade
    await competition.destroy();
将导致生成并执行以下 SQL:
Executing (default): INSERT INTO "team_competitions" ("id","name") VALUES ($1,$2) RETURNING *;
Executing (default): INSERT INTO "competitions" ("id","name","team_competition_id") VALUES ($1,$2,$3) RETURNING *;

// query
Executing (default): SELECT "competition"."id", "competition"."name", "competition"."team_competition_id", "team_competition"."id" AS "team_competition.id", "team_competition"."name" AS "team_competition.name" FROM "competitions" AS "competition" LEFT OUTER JOIN "team_competitions" AS "team_competition" ON "competition"."team_competition_id" = "team_competition"."id";

// cascade deletes
Executing (default): DELETE FROM "team_competitions" WHERE "id" = 1
Executing (default): DELETE FROM "competitions" WHERE "id" = 1

关于javascript - 如何使用 sequelize.js 将表的列设置为外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63449647/

相关文章:

javascript - jQuery 将类添加到包含类元素的 div

node.js - 表单 save mongoose 上随机生成 id

node.js - Google OAuth - 授权时无法读取未定义的属性 '0'

mysql - 关于MYSQL外键和孤行的问题

javascript - 如何与来自 Cheerp/js 的外部变量交互?

javascript - 如何发出不可伪造的跨域请求

mysql - SQL 更新表。一个包含外键

mysql - 判断A表到B表是否没有外键链接的简单方法?

javascript - 更新不相关的 Vue.js 变量导致模板中的输入值消失

mysql - 无法远程连接到 MySQL cPanel 数据库