hydra
hydra copied to clipboard
Database eager relations
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.
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.
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.
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).