How do define relations in PlanetScale(MYSQL) with drizzle-orm?

494 Views Asked by At

I am trying to learn drizzle-orm, but the thing is I am using Planetscale and man its rough. What I wanna do is to give a user a role either an admin or an editor. Also a user with a role of admin will have one or more editors associated with them and, a user with Editor role will have one admin user associated with them. By no means I am an SQL expert, infact I barely know SQL (I have started to look into SQL :)). And the fact that Planetscale does not support foreign keys makes it more difficult to do (for me).

This is the error I am greeted with i try to run drizzle studio to look into my db.

How should I define the desired relations?

➜  galzzy git:(main) ✗ pnpm drizzle-kit studio
No config path provided, using default path
Reading config file '/home/izaan/Work/galzzy/drizzle.config.ts'
/home/izaan/Work/galzzy/node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/drizzle-orm/index-1899b9ae.cjs:4180
    throw new Error(`There is not enough information to infer relation "${sourceTableTsName}.${relation.fieldName}"`);
          ^

Error: There is not enough information to infer relation "users.editors"
    at normalizeRelation (/home/izaan/Work/galzzy/node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/drizzle-orm/index-1899b9ae.cjs:4180:11)
    at /home/izaan/Work/galzzy/node_modules/.pnpm/@[email protected]/node_modules/@drizzle-team/studio/index.cjs:51168:67
    at Array.map (<anonymous>)
    at /home/izaan/Work/galzzy/node_modules/.pnpm/@[email protected]/node_modules/@drizzle-team/studio/index.cjs:51167:42
    at Array.map (<anonymous>)
    at extractRelations (/home/izaan/Work/galzzy/node_modules/.pnpm/@[email protected]/node_modules/@drizzle-team/studio/index.cjs:51166:51)
    at prepareServer (/home/izaan/Work/galzzy/node_modules/.pnpm/@[email protected]/node_modules/@drizzle-team/studio/index.cjs:51198:21)
    at async Command.<anonymous> (/home/izaan/Work/galzzy/node_modules/.pnpm/[email protected]/node_modules/drizzle-kit/index.cjs:53825:18)

Node.js v18.18.0

This is my schema Again I wanna a user with a role of admin will have one or more editors associated with them and, a user with Editor role will have one admin user associated with them.

Am I even approaching the schema design correctly

import {
  int,
  timestamp,
  mysqlTable,
  primaryKey,
  varchar,
  text,
} from 'drizzle-orm/mysql-core';
import type { AdapterAccount } from '@auth/core/adapters';
import { relations } from 'drizzle-orm';

export const users = mysqlTable('user', {
  id: varchar('id', { length: 255 }).notNull().primaryKey(),
  name: varchar('name', { length: 255 }),
  email: varchar('email', { length: 255 }).notNull(),
  emailVerified: timestamp('emailVerified', {
    mode: 'date',
    fsp: 3,
  }).defaultNow(),
  image: varchar('image', { length: 255 }),
  role: varchar<'role', string, ['ADMIN' | 'EDITOR']>('role', {
    length: 6,
  }).notNull(),
  adminId: varchar('adminId', { length: 255 }),
});

export const accounts = mysqlTable(
  'account',
  {
    userId: varchar('userId', { length: 255 }).notNull(),
    type: varchar('type', { length: 255 })
      .$type<AdapterAccount['type']>()
      .notNull(),
    provider: varchar('provider', { length: 255 }).notNull(),
    providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
    refresh_token: varchar('refresh_token', { length: 255 }),
    refresh_token_expires_in: int('refresh_token_expires_in'),
    access_token: varchar('access_token', { length: 255 }),
    expires_at: int('expires_at'),
    token_type: varchar('token_type', { length: 255 }),
    scope: varchar('scope', { length: 255 }),
    id_token: varchar('id_token', { length: 2048 }),
    session_state: varchar('session_state', { length: 255 }),
  },
  (account) => ({
    compoundKey: primaryKey(account.provider, account.providerAccountId),
  })
);

export const sessions = mysqlTable('session', {
  sessionToken: varchar('sessionToken', { length: 255 }).notNull().primaryKey(),
  userId: varchar('userId', { length: 255 }).notNull(),
  expires: timestamp('expires', { mode: 'date' }).notNull(),
});

export const verificationTokens = mysqlTable(
  'verificationToken',
  {
    identifier: varchar('identifier', { length: 255 }).notNull(),
    token: varchar('token', { length: 255 }).notNull(),
    expires: timestamp('expires', { mode: 'date' }).notNull(),
  },
  (vt) => ({
    compoundKey: primaryKey(vt.identifier, vt.token),
  })
);

export const userRelations = relations(users, ({ many, one }) => ({
  accounts: many(accounts),
  sessions: many(sessions),
  editors: many(users, { relationName: 'editors' }),
  adminId: one(users, {
    fields: [users.adminId],
    references: [users.id],
  }),
}));

export const accountsRelations = relations(accounts, ({ one }) => ({
  user: one(users, {
    fields: [accounts.userId],
    references: [users.id],
  }),
}));

export const sessionRelations = relations(sessions, ({ one }) => ({
  user: one(users, {
    fields: [sessions.userId],
    references: [users.id],
  }),
}));

0

There are 0 best solutions below