Sequelizeクエリを作成しようとしていますが、モデルが関連付けられていないことがわかります。 https://github.com/WaltzApp/sequelize-troubleshootingSequelizeは私のモデルが関連付けられていないと思うのはなぜですか?
:しかし、私は関連を宣言した...私はあなた自身のために問題を見てクローンを作成することができレポを作っ
...私は単にだけでなく、私が思ったとして関連を理解していないと思います私はこの問題を抱えている理由は、Sequelizeは複合外部キーをサポートしていないため、私の結合でカスタムon
句を使用する必要がありますが、同じ結合メソッドを指定することができないため、協会自身。これは、Sequelizeが完全に機能するSQLを時々出力する理由を説明しますが、クエリは失敗します(おそらくデータベースクエリは成功しますが、結果をSequelize entiteisに変換できないためです)。
この再生努力の以前のバージョンは、同様に下にコピーされる。
関連モデル
usersRoles:
module.exports = (sequelize, DataTypes) => {
const usersRoles = sequelize.define('usersRoles',
{
key: {
type: DataTypes.UUID,
primary: true,
},
userUid: {
type: DataTypes.UUID,
allowNull: false,
},
roleUid: {
type: DataTypes.UUID,
allowNull: false,
},
oemUid: {
type: DataTypes.UUID,
allowNull: true,
},
propertyManagerUid: {
type: DataTypes.UUID,
allowNull: true,
},
tenantUid: {
type: DataTypes.UUID,
allowNull: true,
},
[MORE FIELDS IRRELEVANT TO MY PROBLEM]
},
{
tableName: 'usersRoles',
indexes: [
{
name: 'userRoleOem',
fields: ['userUid', 'roleUid', 'oemUid'],
unique: true,
where: {
oemUid: { $ne: null },
propertyManagerUid: null,
tenantUid: null,
},
},
{
name: 'userRolePropertyManager',
fields: ['userUid', 'roleUid', 'propertyManagerUid'],
unique: true,
where: {
oemUid: null,
propertyManagerUid: { $ne: null },
tenantUid: null,
},
},
{
name: 'userRoleTenant',
fields: ['userUid', 'roleUid', 'tenantUid'],
unique: true,
where: {
oemUid: null,
propertyManagerUid: null,
tenantUid: { $ne: null },
},
},
{
name: 'compositePK',
fields: ['userUid', 'roleUid', 'oemUid', 'propertyManagerUid', 'tenantUid'],
unique: true,
},
],
freezeTableName: true,
timestamps: false,
});
usersRoles.removeAttribute('id');
usersRoles.associate = (models) => {
models.usersRoles.belongsTo(models.oems, { foreignKey: 'oemUid' });
models.usersRoles.belongsTo(models.propertyManagers, { foreignKey: 'propertyManagerUid' });
models.usersRoles.belongsTo(models.tenants, { foreignKey: 'tenantUid' });
models.usersRoles.belongsTo(models.users, { foreignKey: 'userUid' });
models.usersRoles.belongsTo(models.roles, { foreignKey: 'roleUid' });
models.usersRoles.belongsTo(models.invitations, { as: 'invitation', foreignKey: 'compositePK' });
};
return usersRoles;
};
招待:
module.exports = (sequelize, DataTypes) => {
const invitations = sequelize.define('invitations',
{
uid: {
type: DataTypes.UUID,
primaryKey: true,
},
guestUid: {
type: DataTypes.UUID,
allowNull: true,
},
mappingGroupUid: {
type: DataTypes.UUID,
allowNull: true,
},
invitedByUid: {
type: DataTypes.UUID,
allowNull: false,
},
adminUid: {
type: DataTypes.UUID,
allowNull: true,
},
propertyManagerUid: {
type: DataTypes.UUID,
allowNull: true,
},
tenantUid: {
type: DataTypes.UUID,
allowNull: true,
},
[MORE FIELDS IRRELEVANT TO MY PROBLEM]
}, {
tableName: 'invitations',
freezeTableName: true,
timestamps: false,
});
invitations.associate = (models) => {
models.invitations.belongsTo(models.propertyManagers, { foreignKey: 'propertyManagerUid' });
models.invitations.belongsTo(models.tenants, { foreignKey: 'tenantUid' });
models.invitations.belongsTo(models.mappingGroups, { foreignKey: 'mappingGroupUid' });
models.invitations.belongsTo(models.users, { as: 'guest', foreignKey: 'guestUid' });
models.invitations.belongsTo(models.users, { as: 'invitedBy', foreignKey: 'invitedByUid' });
models.invitations.belongsTo(models.users, { as: 'admin', foreignKey: 'adminUid' });
models.invitations.hasMany(models.usersRoles, { as: 'invitation', foreignKey: 'compositePK' });
};
return invitations;
};
を
invitations
とusersRoles
モデルをmodels.invitations.hasMany(models.usersRoles, { foreignKey: 'compositePK' })
という行に関連付けることに注意してください。
クエリ
const path = require('path');
const glob = require('glob');
const Promise = require('bluebird');
const Sequelize = require('sequelize');
const configs = require('./test/_helpers/getConfigs');
const models = {};
const performQuery = (db) => {
const { usersRoles, invitations } = db; // eslint-disable-line max-len
const sql = {
include: {
model: invitations,
as: 'invitation',
on: {
user: Sequelize.where(
Sequelize.col('usersRoles.userUid'),
'=',
Sequelize.col('invitation.guestUid')),
propertyManager: Sequelize.where(
Sequelize.col('usersRoles.propertyManagerUid'),
'=',
Sequelize.col('invitation.propertyManagerUid')),
tenant: Sequelize.where(
Sequelize.col('usersRoles.tenantUid'),
'=',
Sequelize.col('invitation.tenantUid')),
},
},
};
return usersRoles.findAll(sql);
};
const sequelize = new Sequelize(
configs.get('DB_NAME'),
configs.get('DB_USER'),
configs.get('DB_PSSWD'),
{
dialect: configs.get('DB_TYPE'),
host: configs.get('DB_HOST'),
port: configs.get('DB_PORT'),
});
const modelsPath = path.join(__dirname, 'sequelize/models');
const globOpts = {
cwd: modelsPath,
ignore: '**/index.js',
realPath: false,
nosort: true,
nodir: true,
};
glob('**/*.js', globOpts, (err, files) => {
Promise.map(files, (file) => {
const model = sequelize.import(path.join(modelsPath, file));
models[model.name] = model;
})
.then(() => {
Object.keys(models).forEach((modelName) => {
if (models[modelName].associate) {
models[modelName].associate(models);
}
});
return performQuery(models);
})
.then((res) => {
console.log('SUCCESS', res);
}, (reason) => {
console.error('FAILED', reason);
});
});
出力
FAILED { SequelizeEagerLoadingError: invitations is not associated to usersRoles!
at Function._getIncludedAssociation (.../node_modules/sequelize/lib/model.js:573:13)
at Function._validateIncludedElement (.../node_modules/sequelize/lib/model.js:489:53)
at options.include.options.include.map.include (.../node_modules/sequelize/lib/model.js:385:37)
at Array.map (native)
at Function._validateIncludedElements (.../node_modules/sequelize/lib/model.js:381:39)
at Promise.try.then.then (.../node_modules/sequelize/lib/model.js:1525:14)
at tryCatcher (.../node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (.../node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (.../node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (.../node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (.../node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (.../node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (.../node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (.../node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:637:20)
at tryOnImmediate (timers.js:610:5)
at processImmediate [as _immediateCallback] (timers.js:582:5) name: 'SequelizeEagerLoadingError' }
さらに試み 私は招待状モデルに次の行を追加してみました:
models.usersRoles.belongsTo(models.invitations);
この場合、Sequelizeは実行時に意図した通りに機能するいくつかのSQLを出力しますが、依然としてクエリが機能しないため正しく実行されません。代わりにSequelizeDatabaseError: relation "usersRoles" does not exist
と表示されます。
Executing (default): SELECT "usersRoles"."key", "usersRoles"."userUid", "usersRoles"."roleUid", "usersRoles"."oemUid", "usersRoles"."propertyManagerUid", "usersRoles"."doorSchedule", "usersRoles"."cardId", "usersRoles"."notifyBy", "usersRoles"."contactEmail", "usersRoles"."tenantUid", "usersRoles"."createdAt", "usersRoles"."compositePK", "usersRoles"."invitationUid", "invitation"."uid" AS "invitation.uid", "invitation"."status" AS "invitation.status", "invitation"."guestUid" AS "invitation.guestUid", "invitation"."firstName" AS "invitation.firstName", "invitation"."lastName" AS "invitation.lastName", "invitation"."email" AS "invitation.email", "invitation"."mobile" AS "invitation.mobile", "invitation"."mappingGroupUid" AS "invitation.mappingGroupUid", "invitation"."doorSchedule" AS "invitation.doorSchedule", "invitation"."invitedByUid" AS "invitation.invitedByUid", "invitation"."adminUid" AS "invitation.adminUid", "invitation"."acceptedAt" AS "invitation.acceptedAt", "invitation"."rejectedAt" AS "invitation.rejectedAt", "invitation"."propertyManagerUid" AS "invitation.propertyManagerUid", "invitation"."tenantUid" AS "invitation.tenantUid", "invitation"."contactEmail" AS "invitation.contactEmail", "invitation"."notifyBy" AS "invitation.notifyBy", "invitation"."createdAt" AS "invitation.createdAt", "invitation"."updatedAt" AS "invitation.updatedAt" FROM "usersRoles" AS "usersRoles" LEFT OUTER JOIN "invitations" AS "invitation" ON "usersRoles"."userUid"="invitation"."guestUid" AND "usersRoles"."propertyManagerUid"="invitation"."propertyManagerUid" AND "usersRoles"."tenantUid"="invitation"."tenantUid"; Query failure { SequelizeDatabaseError: relation "usersRoles" does not exist
私はassociate' '呼ぶのですか。私はコードの一部が関連しているとは思わなかったので、それを入れなかった。バグを最小限に抑えるために作成した完全なテストファイルを含めるように質問を編集したばかりだ。見てみましょう。 – Shawn
明白ですが、 'userRoles.associate()'は 'models.invitations'との関係を含まないことがあります。両方の側から関連付けを定義する必要があります。 'models.usersRoles.belongsTo(models.invitations、{foreignKey: 'compositePK'});'。 'foreignKey'も重要で、' compositePK'がどのように定義されているのか分かりません。 – doublesharp
試してみてください(最新の編集をご覧ください)。同じ結果( 'relation" usersRoles "does not exist') – Shawn