简体   繁体   English

续集 hasMany 和belongsTo 问题

[英]Sequelize hasMany and belongsTo issue

I am going to create 2 tables in Mysql using node.js & sequelize.js.我将使用 node.js 和 sequelize.js 在 Mysql 中创建 2 个表。

I have 2 models - User and Company我有 2 个模型 - UserCompany

User has following fields - id - username - password用户有以下字段 - id - 用户名 - 密码

Company has following fields - id - name - owner_id (This is foreign key of id in User, not primary key)公司有以下字段 - id - name - owner_id(这是 User 中 id 的外键,不是主键)

In User model, I added the following code.User模型中,我添加了以下代码。

User.hasMany(Company)

In Company model, I added the following code.Company模型中,我添加了以下代码。

Company.belongsTo(User, { as: 'owner', foreignKey: 'owner_id' });

Now, the problem is that in companies table, I can see that there're 2 columns - owner_id and User_id .现在,问题是在companies表中,我可以看到有 2 列 - owner_idUser_id

Is there any way not to add User_id in sequelize option?有没有办法不在续集选项中添加User_id

Short answer: you should add foreignKey option for User.hasMany(Company) association like this:简短回答:您应该为User.hasMany(Company)关联添加foreignKey选项,如下所示:

User.hasMany(Company, { foreignKey: 'owner_id' });
Company.belongsTo(User, { as: 'owner', foreignKey: 'owner_id' });

Long answer, here is the completed working demo with some simple tests:答案很长,这是带有一些简单测试的完整工作演示:

index.ts : index.ts

import { sequelize } from '../../db';
import { Model, DataTypes, HasManyGetAssociationsMixin, BelongsToGetAssociationMixin } from 'sequelize';
import assert from 'assert';

class User extends Model {
  public id!: number;
  public username!: string;
  public password!: string;
  public getCompanies!: HasManyGetAssociationsMixin<Company>;
}
User.init(
  {
    username: DataTypes.STRING,
    password: DataTypes.STRING,
  },
  { sequelize, modelName: 'User', underscored: true },
);

class Company extends Model {
  public id!: number;
  public name!: string;
  public owner_id!: number;
  public getOwner!: BelongsToGetAssociationMixin<User>;
}
Company.init({ name: DataTypes.STRING }, { sequelize, modelName: 'Company', underscored: true });

User.hasMany(Company, { foreignKey: 'owner_id' });
Company.belongsTo(User, { as: 'owner', foreignKey: 'owner_id' });

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await User.create(
      { username: 'jenifer', password: '123', Companies: [{ name: 'Google' }, { name: 'Twitter' }] },
      { include: [Company] },
    );
    // assertion testing
    const user: User = await User.findByPk(1);
    assert(user.username === 'jenifer', 'The user should be jenifer');
    const companies: Company[] = await user.getCompanies();
    assert(companies.length === 2, 'The count of companies of jenifer should be 2');
    const company1 = companies[0];
    assert(typeof company1['User_id'] === 'undefined', 'User_id column should not be added to company model');
    const owner = await company1.getOwner();
    assert(owner.username === user.username);
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

Data records in database:数据库中的数据记录:

node-sequelize-examples=# select * from "User";
 id | username | password
----+----------+----------
  1 | jenifer  | 123
(1 row)

node-sequelize-examples=# select * from "Company";
 id |  name   | owner_id
----+---------+----------
  1 | Google  |        1
  2 | Twitter |        1
(2 rows)

The execution results of the above code without assertion failure:上面代码没有断言失败的执行结果:

{ POSTGRES_HOST: '127.0.0.1',
  POSTGRES_PORT: '5430',
  POSTGRES_PASSWORD: 'testpass',
  POSTGRES_USER: 'testuser',
  POSTGRES_DB: 'node-sequelize-examples' }
Executing (default): DROP TABLE IF EXISTS "Company" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): DROP TABLE IF EXISTS "User" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "User" ("id"   SERIAL , "username" VARCHAR(255), "password" VARCHAR(255), PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'User' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "Company" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Company" ("id"   SERIAL , "name" VARCHAR(255), "owner_id" INTEGER REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'Company' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "User" ("id","username","password") VALUES (DEFAULT,$1,$2) RETURNING *;
Executing (default): INSERT INTO "Company" ("id","name","owner_id") VALUES (DEFAULT,$1,$2) RETURNING *;
Executing (default): INSERT INTO "Company" ("id","name","owner_id") VALUES (DEFAULT,$1,$2) RETURNING *;
Executing (default): SELECT "id", "username", "password" FROM "User" AS "User" WHERE "User"."id" = 1;
Executing (default): SELECT "id", "name", "owner_id" FROM "Company" AS "Company" WHERE "Company"."owner_id" = 1;
Executing (default): SELECT "id", "username", "password" FROM "User" AS "User" WHERE "User"."id" = 1;

sequelize version:续集版本:

"sequelize": "^5.21.3",

Source code: https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/60190182源代码: https : //github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/60190182

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM