簡體   English   中英

sequelize查詢:響應給了我不存在的列

[英]sequelize querying: response gives me non-exist column

我正在使用ORM sequelize在express.js中創建小型REST API。

我遇到了以下問題:我希望所有客戶都能獲得他們的照片。 我有兩個表Customer和CustomerPhoto與1:1的關系(所以PrimaryKey也是外鍵)

問題是sequelize想要建立一個沒有存在列CustomerPhotoCustomerPhotoID的連接 我怎么能搞清楚? 當我只想從客戶表中獲取所有行時,我遇到了類似的問題。 我用屬性 “解決”了它,只檢索了我確切需要的行。

Customer.js模型:

module.exports = (sequelize, DataTypes) => {
  const Customer = sequelize.define('Customer', {
    customerID: {
      type: DataTypes.INTEGER,
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
    },
    firstname: {
      type: DataTypes.STRING,
      validate: {
        len: [3, 10],
      },
    },
    lastname: {
      type: DataTypes.STRING,
      validate: {
        len: [3, 10],
      },
    },
    phone: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
      unique: true,
      validate: {
        isEmail: true,
      },
    },
  }, {
    classMethods: {
      associate(models) {
        Customer.hasOne(models.CustomerPhoto, { onDelete: 'cascade', hooks: 'true' });
        Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
      },
    },
  });
  return Customer;
};

CustomerPhoto.js模型:

module.exports = (sequelize, DataTypes) => {
  const CustomerPhoto = sequelize.define('CustomerPhoto', {
    customerPhotoID: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER,
      references: {
        model: 'Customer',
        key: 'customerID',
        deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE,
      },
    },
    filename: {
      type: DataTypes.STRING,
      validate: {
        len: [3, 15],
      },
    },
    filetype: {
      type: DataTypes.BLOB,
    },
  }, {
    classMethods: {
      associate(models) {
        CustomerPhoto.hasOne(models.Customer, { onDelete: 'cascade', hooks: 'true' })
      },
    },
  })
  return CustomerPhoto
}


export function fetchCustomers(req, res) {
  models.Customer.findAll({
    attributes: ['firstname', 'lastname', 'phone', 'email', 'filetype'],
    include: [{
      model: models.CustomerPhoto,
      // if true inner join otherwise left join
      required: true,
    }],
  }).then((result) => {
    res.json(result)
  }).catch((error) => {
    res.send(error)
  })
}

我在郵遞員中得到以下回復:

{
  "name": "SequelizeDatabaseError",
  "message": "column \"CustomerPhotoCustomerPhotoID\" does not exist",
  "parent": {
    "name": "error",
    "length": 128,
    "severity": "ERROR",
    "code": "42703",
    "position": "91",
    "file": "parse_relation.c",
    "line": "3183",
    "routine": "errorMissingColumn",
    "sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
  },
  "original": {
    "name": "error",
    "length": 128,
    "severity": "ERROR",
    "code": "42703",
    "position": "91",
    "file": "parse_relation.c",
    "line": "3183",
    "routine": "errorMissingColumn",
    "sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
  },
  "sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
}

好的,這里有一些東西。 首先,您不需要在兩個模型上聲明1:1關系。 只需在一個型號上進行,取決於您的操作方式。

您可以使用belongsTohasOne ,兩者都用於1:1關系,但工作方式不同。

belongsTo在原型模型上創建外鍵,並在目標模型上創建hasOne。 Sequelize甚至建議在大多數情況下使用belongsTo 是鏈接。

“即使它被稱為HasOne關聯,對於大多數1:1關系,你通常需要BelongsTo關聯,因為BelongsTo會在源頭上添加foreignKey,其中hasOne將添加到目標上。”

現在對於您的數據庫模式,您是否真的需要CustomerPhoto的主鍵必須是引用客戶ID模型的外鍵? 我建議您使用CustomerPhotos的常規主鍵,並在Custommer Model上創建一個將創建具有id關聯的列的引用。

classMethods: {
      associate(models) {
        Customer.belongsTo(models.CustomerPhoto, { as : 'CustomerPhotoID', onDelete: 'cascade', hooks: 'true' });
        Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
      },
    },

並在您的查詢調用包括這樣:

models.Customer.findAll({
    attributes: ['firstname', 'lastname', 'phone', 'email', 'filetype'],
    include: [{
      model: models.CustomerPhoto,
      as : 'CustomerPhotoID',
      // if true inner join otherwise left join
      required: true,
    }],
  }).then

“as”argumment將幫助sequelize找到關系的一種說法。

@Ellebkey。 感謝您的回答。 是的,我在你的帖子之前意識到我用hasOne關聯做了這個錯誤。 我修改了我的代碼並改為使用belongsTo 我還在我的Customer表中創建了外鍵, 但這並沒有解決我的問題。

問題在於我的外鍵的定義。 Sequelize默認創建FK但我自己定義它並沒有關聯地編寫它。

在以下示例中,我決定在customer表中將customerPhotoID創建為FK。 之后我將它添加到關聯中。 它的工作原理! 這真的是胡說八道的錯誤。 下次我必須更加小心。

module.exports = (sequelize, DataTypes) => {
  const Customer = sequelize.define('Customer', {
    customerID: {
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.INTEGER,
    },
    customerPhotoID: {
      type: DataTypes.INTEGER,
      references: {
        model: 'Customers',
        key: 'customerID',
        deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE,
      },
    },
    firstname: {
      type: DataTypes.STRING,
      validate: {
        len: [3, 10],
      },
    },
    lastname: {
      type: DataTypes.STRING,
      validate: {
        len: [3, 10],
      },
    },
    phone: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
      unique: true,
      validate: {
        isEmail: true,
      },
    },
  }, {
    classMethods: {
      associate(models) {
        Customer.belongsTo(models.CustomerPhoto, { foreignKey: 'customerPhotoID', onDelete: 'cascade', hooks: 'true' });
        Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
      },
    },
  });
  return Customer;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM