【问题标题】:Sequelize belongTo association giving error "table name "contact" specified more than once"Sequelize belongsTo 关联给出错误“表名“联系人”指定了不止一次”
【发布时间】:2020-06-12 00:39:27
【问题描述】:

我正在尝试通过contact_phone 模型将phone 模型连接到contact 模型。当我.findAll 如下所示时,错误返回:未处理的拒绝 SequelizeDatabaseError:表名“联系人”指定了多次。在这种情况下,关联/“as”是否正确?当我尝试包含 contact_phone 模型时会发生错误。我还插入了带有初始电话行的表格。

exports.findAll = (req, res) => {
  models.contact.findAll({
    include: [
      { 
        model: models.contact_phone, 
        as: 'contact'
      } 
    ]
  })
    .then(contacts => {
    res.status(200).send(contacts);
  });
};

模型

module.exports = (sequelize) => {
  const Contact = sequelize.define(
    'contact',
    {
      contact_id: {
        type: Sequelize.BIGINT,  
        primaryKey: true,
        autoIncrement: true,
        field: 'contact_id'
      },
      first_name: {
        type: Sequelize.STRING,
        field: 'first_name'
      },
      last_name: {
        type: Sequelize.STRING,
        field: 'last_name',
      },
      created_at: {
        type: Sequelize.DATE,
        field: 'created_at'
      },
      updated_at: {
        type: Sequelize.DATE,
        field: 'updated_at'   
      }
    },
    {
      tableName: 'contacts',
      freezeTableName: true,
    }
  );

  Contact.associate = (models) => {
    Contact.belongsTo(models.contact_phone, {foreignKey: 'contact_id', as: 'contact'});
    Contact.hasOne(models.phone, {foreignKey: 'phone_id', through: models.contact_phone});
  };

  return Contact;
};

module.exports = (sequelize) => {
  const ContactPhone = sequelize.define(
    'contact_phone',
    {
      contact_id: {
        type: Sequelize.BIGINT,
        references: {
          model: 'contact',
          key: 'contact_id'
        }
      },
      phone_id: {
        type: Sequelize.STRING,
        references: {
          model: 'phone',
          key: 'phone_id'
        }
      }
    }
  );

  ContactPhone.associate = (models) => {
    ContactPhone.belongsTo(models.phone, {foreignKey: 'phone_id', as: 'phone'});
    ContactPhone.belongsTo(models.contact, {foreignKey: 'contact_id', as: 'contact'});
  };

  return ContactPhone;
};

module.exports = (sequelize) => {
  const Phone = sequelize.define(
    'phone',
    {
      phone_id: {
        type: Sequelize.STRING,
        primaryKey: true,
        field: 'phone_id'
      },
      updated_at: {
        type: Sequelize.DATE,
        field: 'updated_at'        
      },
      created_at: {
        type: Sequelize.DATE,
        field: 'created_at'
      }
    },
    {
      tableName: 'phones',
      freezeTableName: true,
    }
  );

  Phone.associate = (models) => {
    Phone.belongsTo(models.contact, {foreignKey: 'phone_id', through: models.contact_phone});
  };

  return Phone;
};

【问题讨论】:

    标签: javascript node.js postgresql sequelize.js


    【解决方案1】:

    你可以这样做。您没有包含额外的contact_phone,您可以像这样直接使用联系人和电话进行关联。

    联系模块:

    module.exports = (sequelize) => {
        const Contact = sequelize.define(
            'contact',
            {
                contact_id: {
                    type: Sequelize.INT,
                    primaryKey: true,
                    autoIncrement: true,
                    field: 'contact_id'
                },
                first_name: {
                    type: Sequelize.STRING,
                    field: 'first_name'
                },
                last_name: {
                    type: Sequelize.STRING,
                    field: 'last_name',
                },
                created_at: {
                    type: Sequelize.DATE,
                    field: 'created_at'
                },
                updated_at: {
                    type: Sequelize.DATE,
                    field: 'updated_at'
                }
            },
            {
                tableName: 'contacts',
                freezeTableName: true,
            }
        );
    
        Contact.associate = (models) => {
            Contact.hasOne(models.phone, { // has many or hasOne relationship .here read like contact has one phone 
                foreignKey: 'phone_id',
                onDelete: "CASCADE"
            });
        };
    
        return Contact;
    };
    

    手机模块:

    module.exports = (sequelize) => {
        const Phone = sequelize.define(
            'phone',
            {
                phone_id: {
                    type: Sequelize.INT,
                    primaryKey: true,
                    autoIncrement: true,
                    field: 'phone_id'
                },
                contact_id: {
                    type: Sequelize.INT,
                },
                updated_at: {
                    type: Sequelize.DATE,
                    field: 'updated_at'
                },
                created_at: {
                    type: Sequelize.DATE,
                    field: 'created_at'
                }
            },
            {
                tableName: 'phones',
                freezeTableName: true,
            }
        );
    
        Phone.associate = (models) => {
            Phone.belongsTo(models.contact, {
                foreignKey: 'contact_id',
                as: 'contact',
                onDelete: "CASCADE"
            });
        };
    }
    

    您的查询类似于:

    models.contact.findAll({
        include: [
            {
                model: models.phone,
                as: 'contact'
            }
        ]
    }).then(contacts => {
        res.status(200).send(contacts);
    });
    

    编辑:

    如何定义更多同键不同别名的关联

    Phone.associate = (models) => {
        Phone.belongsTo(models.contact, {
            foreignKey: 'contact_id',
            as: 'contact',
            onDelete: "CASCADE"
        });
        Phone.belongsTo(models.contact, {
            foreignKey: 'contact_id',
            as: 'phone',
            onDelete: "CASCADE"
        });
    };
    

    【讨论】:

    • 感谢您的回复!有没有办法用中间模块做到这一点?此外还有其他中间模块,例如organization_phone,它们将充当phoneorganization 之间的中间模块
    • 或者在那种情况下,我应该将organization 模块的primaryKey 和foreignKey 也添加到手机module
    • 是的,我们可以拥有多个外键,因此将来当您想要触发 group_by 和 count 、 sum 之类的查询时会很容易。
    • 如果我们添加第三个模块来连接两个模块,而不是总是需要管理第三个模块,这会增加查询的复杂性。它可能会影响您的查询响应时间。
    • @ckingchris 如果这符合您的要求,请按照标记进行。
    猜你喜欢
    • 2019-02-15
    • 2013-10-05
    • 1970-01-01
    • 2018-07-13
    • 2016-04-11
    • 2017-08-18
    • 2015-04-17
    • 2021-05-12
    • 2018-06-14
    相关资源
    最近更新 更多