Sequelize.js 如何通过编程确定sequelize模型属性';s是外键,它指的是什么型号

Sequelize.js 如何通过编程确定sequelize模型属性';s是外键,它指的是什么型号,sequelize.js,Sequelize.js,我正在尝试为我的应用程序创建一个动态更新函数,它可以做两件事 -检查新值是否与旧值不同,以避免更新,从而在没有实际更改值的情况下,在时间戳更改更新的_ -检查用户想要更改的属性之一是否为外键,然后检查所述用户修改是否引用了引用模型中的实际行,以避免出现错误 因此,我需要一种从模型中动态提取属性信息的方法,更准确地说,我需要能够检查属性是否是外键,如果是外键,我需要找到它所引用的模型的名称。。。看起来您可以在所有模型的第一部分使用挂钩。我同意Ken的观点,你的数据库已经阻止你这么做了,因此你可以捕

我正在尝试为我的应用程序创建一个动态更新函数,它可以做两件事

-检查新值是否与旧值不同,以避免更新,从而在没有实际更改值的情况下,在时间戳更改更新的_

-检查用户想要更改的属性之一是否为外键,然后检查所述用户修改是否引用了引用模型中的实际行,以避免出现错误


因此,我需要一种从模型中动态提取属性信息的方法,更准确地说,我需要能够检查属性是否是外键,如果是外键,我需要找到它所引用的模型的名称。。。看起来您可以在所有模型的第一部分使用挂钩。我同意Ken的观点,你的数据库已经阻止你这么做了,因此你可以捕获错误并自定义你想要发送的内容,而不是添加一堆预防性代码。。显然,您可以通过某种方式确定输入的预期目标是哪个模型,因此您不必担心访问属性数据。

如果有人需要,我可以这样做:

///////////////////////////////////////////////////////////////////////
// Unique keys checks

const hasUniqueConflicts = async (model, parameters)=>{

  const uniqueFields = getUniqueFields(model, Object.keys(parameters))
  const returns = new Set()
  const uniqueParameters = uniqueFields.map(field=>{return {[field]:parameters[field]}})
  // Check if any of the values of the unique fields already exists
  const results = await model.findAll({where:{[Op.or]:uniqueParameters}})

  if(results.length){
    for(result of results){
      for (field of uniqueFields){
        if(parameters[field] === result[field]) returns.add(field)
      }
    }
    return Array.from(returns)
  }

  return false
}


///////////////////////////////////////////////////////////////////////
// Foreign keys checks

const hasForeignKeyProblems = async (model, parameters)=>{
  const foreignKeys = getForeignKeys(model, Object.keys(parameters))
  const returns = new Set()

  for(field of foreignKeys){
    const valid = referencedRowExists(model, field, parameters[field])
    if (!valid) returns.add(field)
  }

  if (returns.size) return Array.from(returns)
  return false
}

//////////////////////////////////////////////////////////////
const referencedRowExists = async (model, foreignKey, foreignKeyValue)=>{
  if(foreignKeyValue === null && isNullable(model, foreignKey)) return true

  const models = getModels(model)
  const tableName = getReferencedTableName(model, foreignKey)
  for (table in models){
      if (models[table].tableName == tableName){
          referenceExists = await rowExists(models[table], foreignKeyValue)
          if (referenceExists) return true
          break
      }
  }
  return false
}

const isNullable = (model, fieldName) => model.rawAttributes[fieldName].allowNull

const IsUnique = (model, fieldName) => model.rawAttributes[fieldName].unique

const IsForeignKey = (model, fieldName) => model.rawAttributes[fieldName].references && true

const getModels = (model) => model.sequelize.models

const getUniqueFields = (model, fieldNames) => fieldNames.filter(field=>IsUnique(model, field))

const getForeignKeys = (model, fieldNames) => fieldNames.filter(field=>IsForeignKey(model, field))

const getReferencedTableName = (model, foreignKey) => model.rawAttributes[foreignKey].references.model

const rowExists = async (model, parameter) => Object.keys(parameter).length ? !!(await model.count({where: parameter})) : false

关于外键,似乎您正在尝试编写已经在DBMS中实现的代码。这是一个很大的工作!我认为您最好将精力花在编写代码来处理外键错误上(即通知用户等)。(我很喜欢你的另一个想法,寻找实际的更改)如果外键错误,没有足够的数据,这意味着它没有提到遇到问题的字段名,因此你可以准确地告诉问题所在的用途,对于唯一值,它只给你有问题的第一个唯一字段,而不是所有字段,这也不理想,因为在表单中需要它例如,为了给用户准确的反馈,经过多次尝试和出错后,我设法做了我需要做的事情我设法做了我需要做的事情,但是sequelize错误对于我的用例来说还不够好,这里有一些例子:-案例1:你有用户注册,用户输入已使用的用户名和已使用的电子邮件,您只需尝试创建用户并捕获sequelize错误,该错误仅包含其中一个字段的信息,因此您无法准确地提供用户所需的所有反馈-案例2:您有一个具有多个外键的模型,你的用户以某种方式发送了一个请求,其中一个外键指向一个不存在的引用,你如何准确地告诉用户他在哪里出了问题?当sequelize约束错误没有提到字段名时,我也不喜欢像我这样做,但我不知道我还能如何给出完整准确的反馈当你说sequelize error时,你的意思是postgres抛出的错误吗?是的,它肯定只给出关于第一个问题的反馈,关于设置消息,我还没有尝试过,因为我不需要它,我正在构建一个api,我有一个自定义错误对象和一个自定义错误处理程序,它只需要一个代码和一个对象就可以知道确切的问题是什么,并将其发送回用户,而不会泄漏任何关键信息