I have this dummy project: drizzle-question-relations.zip which contains these files:
/src/db/schema.ts
/**
* This code snippet is from the drizzle-orm documentation:
* https://orm.drizzle.team/docs/rqb#many-to-many
*/
import { relations } from 'drizzle-orm';
import {
integer,
pgTable,
primaryKey,
serial,
text,
} from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name'),
});
export const usersRelations = relations(users, ({ many }) => ({
usersToGroups: many(usersToGroups),
}));
export const groups = pgTable('groups', {
id: serial('id').primaryKey(),
name: text('name'),
});
export const groupsRelations = relations(groups, ({ many }) => ({
usersToGroups: many(usersToGroups),
}));
export const usersToGroups = pgTable(
'users_to_groups',
{
userId: integer('user_id')
.notNull()
.references(() => users.id),
groupId: integer('group_id')
.notNull()
.references(() => groups.id),
},
(t) => ({
pk: primaryKey({ columns: [t.userId, t.groupId] }),
})
);
export const usersToGroupsRelations = relations(usersToGroups, ({ one }) => ({
group: one(groups, {
fields: [usersToGroups.groupId],
references: [groups.id],
}),
user: one(users, {
fields: [usersToGroups.userId],
references: [users.id],
}),
}));
The content of that file is taken from: https://orm.drizzle.team/docs/rqb#many-to-many
I’m trying to understand the necessity of defining these specific relations in the ORM schema:
export const usersRelations = relations(users, ({ many }) => ({
usersToGroups: many(usersToGroups),
}));
export const groupsRelations = relations(groups, ({ many }) => ({
usersToGroups: many(usersToGroups),
}));
export const usersToGroupsRelations = relations(usersToGroups, ({ one }) => ({
group: one(groups, {
fields: [usersToGroups.groupId],
references: [groups.id],
}),
user: one(users, {
fields: [usersToGroups.userId],
references: [users.id],
}),
}));
While I acknowledge that there are likely significant reasons for including these relational definitions in the ORM schema, I’m still exploring the tangible benefits they offer. Specifically, I’m interested in understanding the additional capabilities and functionalities that these relations enable, maybe the ability to perform specific types of queries or benefiting from enhanced code completion (IntelliSense), etc, etc.
From my initial experiments, I haven’t observed any differences between the version of the code with these relations defined and the version without them.
I’m particularly curious if these relations facilitate certain operations that I might not have tested yet. Otherwise I prefer to use the simplest code version.
Here I have a test file:
/src/__tests__/user.test.ts
import { eq } from 'drizzle-orm';
import { client, db } from '../db';
import { groups, users, usersToGroups } from '../db/schema';
describe('User and Group relationships', () => {
afterAll(async () => {
await client.end();
});
test('should retrieve user details along with group names', async () => {
const usersResult = await db
.select()
.from(users)
.innerJoin(usersToGroups, eq(users.id, usersToGroups.userId))
.innerJoin(groups, eq(usersToGroups.groupId, groups.id))
.where(eq(groups.id, 1));
expect(usersResult).toBeDefined();
expect(usersResult.length).toBeGreaterThan(0);
usersResult.forEach((user) => {
expect(user).toBeDefined();
expect(user.groups.name).not.toBeNull();
});
});
});
You can setup the code above and run it by doing the following (this requires a docker engine):
- download file: drizzle-question-relations.zip
- extract content in directory:
drizzle-question-relations
- then do:
$ cd drizzle-question-relations
$ pnpm i
$ clear; pnpm db:reset-push-seed
$ pnpm test
Thanks in advance!