2017-11-01 16 views
0

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

invitationsusersRolesモデルを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

答えて

0

モデルが互いに関連付けされていないので、あなたはModel.associate()メソッドを呼び出すことはありません。そのトリックは、アソシエーションがまだ定義されていないモデルを必要とする可能性があるため、アソシエートは最後に来なければなりません。モデルをロードした後、それらをループし、model.associate(models)を呼び出して関連付けを作成します。

userRoleの定義には、invitationsへの関連付けも含まれません。 Sequelizeでは、問合せ元の側からリレーションシップを定義するか、両方のオブジェクトからリレーションシップを問い合せる場合は両方を定義する必要があります。 invitationsにはuserRolesが多数あるため、userRolesinvitationsに属しています。クエリでテーブルをinvitationと参照しているため、おそらくas属性でアソシエーションのエイリアスを設定する必要があります。

userRoles

models.usersRoles.belongsTo(models.invitations, { 
    as: 'invitation', 
    foreignKey: 'compositePK', 
}); 
+0

私はassociate' '呼ぶのですか。私はコードの一部が関連しているとは思わなかったので、それを入れなかった。バグを最小限に抑えるために作成した完全なテストファイルを含めるように質問を編集したばかりだ。見てみましょう。 – Shawn

+0

明白ですが、 'userRoles.associate()'は 'models.invitations'との関係を含まないことがあります。両方の側から関連付けを定義する必要があります。 'models.usersRoles.belongsTo(models.invitations、{foreignKey: 'compositePK'});'。 'foreignKey'も重要で、' compositePK'がどのように定義されているのか分かりません。 – doublesharp

+0

試してみてください(最新の編集をご覧ください)。同じ結果( 'relation" usersRoles "does not exist') – Shawn

関連する問題