Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize.js: join tables without associations

Tags:

Is there a way to join tables that don't have associations defined using include in sequelize? This is not a duplicate of this. I am talking about tables that are not associated at all but having columns that I want to join on.

Example:

select * from bank left outer join account      on account.bank_name = bank.name 

The above query will return all records in table bank regardless of the existence of an account record where the specified constraints apply.

In sequelize this would look something like the following, if models bank and account were associated on account.bank_name = bank.name:

bank.findAll({     include: [{         model: account,         required: false,     }] }) 

However, what if the models are not associated? Is there a way to write my own custom on section or equivalent:

bank.findAll({     include: [{         model: account,         required: false,         on: {             bank_name: Sequelize.col('bank.name')         }     }] }) 

I vaguely remember reading something about this but I cannot seem to find that doc anywhere now. If you can point to the correct section in the docs it would be greatly appreciated.

like image 721
AlexanderF Avatar asked Nov 10 '17 05:11

AlexanderF


1 Answers

It seem that while it is possible to define a custom on condition, it is not possible to include relations without defining associations first. This is implied by the documentation wording for findAll method (search for options.include on page):

A list of associations to eagerly load using a left join. Supported is either { include: [ Model1, Model2, ...]} or { include: [{ model: Model1, as: 'Alias' }]} or { include: ['Alias']}. If your association are set up with an as (eg. X.hasMany(Y, { as: 'Z }, you need to specify Z in the as attribute when eager loading Y).

The docs on options.include[].on are even more terse:

Supply your own ON condition for the join.

I ended up solving my problem using Postgres views as a workaround. It is also possible to inject a raw query and bypass sequelize limitations but I would use that only as a development / prototyping hack and come up with something more robust / secure in production; something like views or stored procedures.

like image 133
AlexanderF Avatar answered Sep 20 '22 20:09

AlexanderF