mysql - 如何将两个模型与续集关联?(1:n) 和 (m:n)
问题描述
我想做3张桌子Cliente
,Obra
和Engenheiro
。
关联:Cliente
与Obra
(1:n) 相关并Engenheiro
与Obra
(m:n) 相关。
客户端.js:
const db = require('./db');
const Obra = require('./Obra');
const Cliente = db.sequelize.define('clientes', {
nome: {
type: db.Sequelize.STRING
},
celular: {
type: db.Sequelize.STRING
},
cpf: {
type: db.Sequelize.STRING
}
});
Cliente.hasMany(Obra);
//Cliente.sync({force: true})
module.exports = Cliente
Engenheiro.js:
const db = require('./db');
const Registro = require('./Registro');
const Engenheiro = db.sequelize.define('engenheiros', {
nome: {
type: db.Sequelize.STRING
}
crea: {
type: db.Sequelize.STRING
},
salario: {
type: db.Sequelize.FLOAT
}
});
Engenheiro.hasMany(Obra);
//Engenheiro.sync({force: true})
module.exports = Engenheiro
Obra.js:
const db = require('./db')
const Cliente = require('./Cliente');
const Registro = require('./Registro');
const Obra = db.sequelize.define('obras', {
bairro: {
type: db.Sequelize.STRING
},
cidade: {
type: db.Sequelize.STRING
},
estado: {
type: db.Sequelize.STRING
}
});
Obra.belongsTo(Cliente);
Obra.hasMany(Engenheiro);
//Obra.sync({force: true})
module.exports = Obra
当我调用“node something.js”时出现错误消息:
“something.hasMany 调用的东西不是 Sequelize.Model 的子类”
更新:
我尝试了 Anatoly 所说的,它执行时没有任何错误,但我没有看到新的出现列并且控制台上没有出现关联的sql代码,我做错了吗?
我创建了一个新模型“Registro.js”并将“.sync()”和关联移动到一个新文件:
Association.js
const Cliente = require('./Cliente');
const Engenheiro = require('./Engenheiro');
const Obra = require('./Obra');
const Registro = require('./Registro');
Cliente.sync({force: true});
Engenheiro.sync({force: true});
Obra.sync({force: true});
Registro.sync({force: true});
Cliente.hasMany(Obra);
Obra.belongsTo(Cliente);
Obra.belongsToMany(Engenheiro, { through: Registro });
Engenheiro.belongsToMany(Obra, { through: Registro });
Registro.js(所有模型都遵循相同的结构):
const db = require('./db');
const Registro = db.sequelize.define('registros', {});
module.exports = Registro
控制台(表格看起来更大,因为我添加了新列):
Executing (default): DROP TABLE IF EXISTS `clientes`;
Executing (default): DROP TABLE IF EXISTS `engenheiros`;
Executing (default): DROP TABLE IF EXISTS `obras`;
Executing (default): DROP TABLE IF EXISTS `registros`;
Executing (default): CREATE TABLE IF NOT EXISTS `clientes` (`id` INTEGER NOT NULL auto_increment , `nome` VARCHAR(255), `end` VARCHAR(255), `fone` VARCHAR(255), `celular` VARCHAR(255), `cpf` VARCHAR(255), `cnpj` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `obras` (`id` INTEGER NOT NULL auto_increment , `end` VARCHAR(255), `bairro` VARCHAR(255), `cidade` VARCHAR(255), `estado` VARCHAR(255), `metragem` VARCHAR(255), `quartos` VARCHAR(255), `wc` VARCHAR(255), `infraestrutura` TINYINT(1), `garagem` TINYINT(1), `andar` VARCHAR(255), `edificio` VARCHAR(255), `situacao` VARCHAR(255), `dataInicio` DATETIME, `dataTermino` DATETIME, `observacao` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `engenheiros` (`id` INTEGER NOT NULL auto_increment , `nome` VARCHAR(255), `end` VARCHAR(255), `fone` VARCHAR(255), `celular` VARCHAR(255), `cpf` VARCHAR(255), `crea` VARCHAR(255), `salario` FLOAT, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): CREATE TABLE IF NOT EXISTS `registros` (`id` INTEGER NOT NULL auto_increment , `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `clientes`
Executing (default): SHOW INDEX FROM `obras`
Executing (default): SHOW INDEX FROM `engenheiros`
Executing (default): SHOW INDEX FROM `registros`
Update2:
我设法通过将关联放在之前.sync()
并更改force
为来创建关系列,alter
但我仍然不明白关联是如何工作的。
在下面的示例中,当我更改.sync(alter: true)
某些表的顺序时,既没有创建也没有更新,并且关联失败。
const Cliente = require('./Cliente');
const Obra = require('./Obra');
const Engenheiro = require('./Engenheiro');
const Registro = require('./Registro');
Cliente.hasMany(Obra);
Obra.belongsTo(Cliente);
Obra.belongsToMany(Engenheiro, {through: Registro});
Engenheiro.belongsToMany(Obra, {through: Registro});
Obra.sync({alter: true});
Engenheiro.sync({alter: true});
Cliente.sync({alter: true});
Registro.sync({alter: true});
为什么sync(force:true)
导致代码失败以及为什么sync
事情的顺序?
解决方案
首先,您需要做的是将所有关联定义移到模型文件之外,或者将它们添加到模型的associate
方法中,以便在所有模型都已注册后稍后调用它们,例如,请参见我的答案。
其次,如果您需要 M:N 关联,您应该创建一个附加表并定义一个模型(例如它的名称EngenheiroObra
)以链接Engenheiro
到模型的Obra
usingbelongsToMany
方法。
Engenheiro.belongsToMany(Obra, { though: EngenheiroObra });
Obra.belongsToMany(Engenheiro, { though: EngenheiroObra });
更新。如果您已经将模型文件移到外部,您还需要从模型文件中删除所有关联定义。而且你不需要旧的hasMany
联想,因为你用旧的联想代替了它们belongsToMany
。
推荐阅读
- php - 为每个产品字段添加一个子字段 - Symfony Forms
- java - 我在 java.sql.BatchUpdateException 中遇到错误:ORA-00917:缺少逗号
- mysql - 为什么ansible无法连接MySql?
- katalon-studio - Katalon Analytics 未显示从测试集合执行的所有测试套件的结果
- c# - 从可观察集合中绑定组合框项目源时遇到问题
- java - 使用 ContentCachingRequestWrapper 后缺少所需的请求正文
- javascript - 在服务器上创建 Zip 存档并在客户端下载
- jena - 有谁知道如何让 tdb2.dump 命令真正做任何事情
- sql - 在 oracle sql 中从包含 XML 格式字符串的列中获取子字符串
- apache-spark - 如何将多个列作为参数传递给 Spark 数据框