hydra icon indicating copy to clipboard operation
hydra copied to clipboard

Database eager relations

Open ondratra opened this issue 3 years ago • 3 comments

When using db.get provided by @dzlzv/hydra-common's DatabaseManager like this:

// input schema
type Video @entity {
  channel: Channel
  license: License
  ...
}

// db.get in mappings
const video = await db.get(Video, { where: { id: videoId.toString() } as FindConditions<Video> })

a flat video record without related objects loaded is returned

Video {
  channelId: '3',
  licenseId: '1',
  ...
}

// instead of what I expected
Video {
    channel: Channel { ... },
    license: License { ... },
}

There is a way to load related object by enumareting them in db.get parameters. That works, but a) only 1 level deep e.g. I can access video.channel, but can't access video.channel.category.name. b) brings extra complexity to mappings c) requires keeping list of relations in mappings See https://github.com/typeorm/typeorm/blob/51b2a63d/src/find-options/FindOneOptions.ts#L23

const video = await db.get(Video, { where: { id: videoId.toString() } as FindConditions<Video>, relations: ['channel', 'license'] })

From what I found there is a way to automatically load related objects if we expose typeorm's find* functions (preferebly) or QueryBuilder in DatabaseManager. See https://orkhan.gitbook.io/typeorm/docs/eager-and-lazy-relations

If we introduce find* functions, https://github.com/Joystream/hydra/issues/370 will be solved as well.

ondratra avatar Apr 30 '21 09:04 ondratra

Do we always want to eagerly load all the relations? I am not sure always setting { eager: true } in the schema is the best approach, perhaps a better solution would be to have an option in the DatabaseManager get/find methods.

dzhelezov avatar May 18 '21 07:05 dzhelezov

What are the downside of default { eager: true } - "only" decrease of performance? I expected to have access to all relevant data after .get() without worrying about anything not being loaded (thus preventing errors caused by forgetting to load something extra). But if there are significant downsides, I wouldn't mind adding this eager directive explicitly wherever it is needed.

ondratra avatar May 28 '21 09:05 ondratra

Yeah, the problem is that the typeorm metadata is shared across the query node server and the mappings. Eager fetching is totally all right for the mappings, but the query node itself may suffer if the relations are always fetched eagerly, no matter which data was requested. So I'd prefer a solution when the mapping developer simply can choose if the relations should be loaded eagerly or not (same with update cascading).

dzhelezov avatar May 28 '21 12:05 dzhelezov