2017-05-06 4 views
1

ORMを使用してexpress.jsに小さなREST APIを作成しています。sequelize querying:レスキューが私に存在しない列を与えます

私は以下の問題に遭遇しました: 私は彼らの写真ですべての顧客を取得したいと思います。問題はsequelizeはありませんが存在コラムCustomerPhotoCustomerPhotoIDに参加したいと思いますということです

(その主キーも外部キーである)1関係:私は1と2つのテーブルカスタマーとCustomerPhotoを持っています。どのように私は把握することができますか?顧客テーブルからすべての行だけを欲しかったとき、同様の問題に遭遇しました。私はそれを属性で "解決"し、私が必要とする行だけを取り出しました。

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';" 
} 

答えて

0

[OK]を、いくつかあります。ここにあるものすべて。まず、両方のモデルで1:1の関係を宣言する必要はありません。ただ1つのモデルでそれをやって、それをどうやって行うかによって異なります。

あなたは両方が1のために使用されている、belongsToのまたはhasOneのを使用することができます:1の関係が異なる動作します。

belongsTo発信元モデルに外部キーを作成し、宛先モデルにhasOneを作成します。ほとんどの場合、belongsToを使用することをお勧めします。 Hereがリンクです。

「ほとんどの1のためにそれがhasOneの関連付けと呼ばれていますが、:。belongsToのはhasOneのは、ターゲットに追加するソースに のForeignKeyが追加されますので、あなたは通常、belongsTo関連をしたい 1の関係」

ここで、dbスキーマの場合、CustomerPhotoのプライマリキーはCustomer ID Modelを参照する外部キーである必要がありますか?私はCustomerPhotosのために通常のプライマリキーを使用することをお勧めしますし、IDの関連付けを持つ列を作成するCustommer Modelのリファレンスを作成するだけです。

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

と、クエリに次のように含ま呼び出す:argummentはsequelizeが話すの関係の並べ替えを見つけましょう「と」

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 

0

@Ellebkey。ご回答有難うございます。はい、私はhasOneとこの間違いをしたことをあなたの記事の前に気づいた。コードを変更してbelongsToを代わりに使用しました。私はまた私の問題を解決しなかったしかし外のキーを作成しました。

問題は私の外部キーの定義にありました。 SequelizeはデフォルトでFKを作成しますが、私はそれを自分で定義し、それを関連付けることはしませんでした。

次の例では、カスタマーテーブルに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; 
}; 
関連する問題