如何在Sequelize中的关系N-M中生成伪造记录

时间:2019-05-18 22:57:47

标签: javascript sequelize.js

我有两个表:UserScope;基数为N(User-> M(Scope)。当我在UserScope表中插入伪造记录时,一切正常,但是如果我在UserScope表中插入伪造记录(来自UserScopeUser表的ID) Scope关系表,它代表Unhandled rejection SequelizeUniqueConstraintError: Validation error Unhandled rejection SequelizeForeignKeyConstraintError: Cannot add or update a child row: a foreign key constraint fails (`graph`.`userScope`, CONSTRAINT 'userScope_ibfk_1' FOREIGN KEY (`scopeId`) REFERENCES `scope` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) 之间的关系,我收到错误消息:

1:

SHOW ENGINE INNODB STATUS\G

2:

CONSTRAINT 'userScope_ibfk_1' FOREIGN KEY ('scopeId') REFERENCES 'scope' ('id') ON DELETE CASCADE ON UPDATE CASCADE
Trying to add in child table, in index userScope_userId_scopeId_unique tuple:
DATA TUPLE: 3 fields;
 0: len 4; hex 80000008; asc     ;;
 1: len 4; hex 8000000a; asc     ;;
 2: len 4; hex 80000001; asc     ;;

But in parent table 'graph'. 'scope', in index PRIMARY,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 696e66696d756d00; asc infimum ;;

我曾尝试通过MySQL控制台(import db from "./models"; import faker from "faker"; import times from "lodash.times"; import random from "lodash.random"; const amount = 10; db.user.bulkCreate( times(amount, () => ({ email: faker.internet.email(), password: faker.internet.password(), name: `${faker.name.firstName} ${faker.name.lastName}`, birth: Date.now() })) ) db.scope.bulkCreate( times(amount, () => ({ title: faker.hacker.verb() })) ) db.userScope.bulkCreate( times(amount, () => ({ scopeId: random(1, amount), userId: random(1, amount) })) ); )进行调试:

UserScope

我发现了this这个问题,使我认为我在关系表中插入数据的方式不正确,例如,在关系表中添加了重复关系。

我以这种方式插入关系:

amount

表格:

enter image description here

enter image description here

我希望在1表中插入伪造的关系,没有任何错误,并且是随机的。

Obs:我已经将{{1}}设置为{{1}} /手动设置了ID,但仍然收到此错误。我也已经读过this个,this一个这样的线程,但是...

1 个答案:

答案 0 :(得分:1)

可能导致问题的情况:

  1. 对于unique字段,字段具有约束unique,并且行具有重复的值

  2. 一个表引用了另一个没有可追溯完整性约束的表

  3. 引用表的行值与某些引用的键值不匹配

  4. 主键的数据类型不同,例如,MySQL有时会针对同一数据类型以不同的方式转换类型

我的案子是第一个。我正在使用Lodashrandom函数和Faker的函数,但是没有可用的函数对我有帮助。我研究发现Chance,但是这仍然没有帮助,所以我编写了脚本以生成随机值并以不重复的方式使用它:

const randomNumbers = (length, start=1) => {
  let array = [...Array(length).keys()].map(value => start + value);

  array.sort(() => Math.random() - 0.5);

  return array;
};

export { randomUniqueNumbers };

在模型中:

// ...

import { randomUniqueNumbers } from "./util";

let scopeIds = randomUniqueNumbers(length);

let userIds = randomUniqueNumbers(length);

db.userScope
  .bulkCreate(
    times(length, () => ({
      scopeId: scopeIds.pop(),
      userId: userIds.pop()
    }))
  )
  .then(userScope => {})
  .catch(error => console.log(error));

我在Github上的项目。

关系:

enter image description here

为了测试N-M关系,我在关系表中添加了另一行,以证明一个范围可以用于一个或多个用户:

INSERT INTO userScope(createdAt, updatedAt, scopeId, userId) VALUES(STR_TO_DATE('18,05,2019','%d,%m,%Y'), STR_TO_DATE('18,05,2019','%d,%m,%Y'), 1, 1);

肥胖:如果您不喜欢Graph QL + Sequelize + Node,我建议使用Prisma软件包。

Obs²:对具有unique字段的其他表应用相同的想法

肥胖³:另一种选择是实现自己的使用种子概念的功能,例如Numpy Random

参考文献:

Cannot add or update a child row a foreign key constraint fails

MySQL error 1452

Foreign key

Unique

Sequelize belongs to many

Foreign key MySQL