drizzle-team / drizzle-kit-mirror

Docs and issues repository for drizzle-kit
287 stars 16 forks source link

[FEATURE]: drizzle-kit introspect should generate relation in generated schema.ts #202

Open conanak99 opened 9 months ago

conanak99 commented 9 months ago

Describe what you want

Currently, running drizzle-kit introspect:{dialect} command lets you pull DDL from an existing database and generate schema.ts.

However, the generated schema.ts only contains the declaration for each table. Example:

import { pgTable, serial, text, integer, jsonb } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

export const users = pgTable('users', {
    id: serial('id').primaryKey(),
    name: text('name'),
});

export const profileInfo = pgTable('profile_info', {
    id: serial('id').primaryKey(),
    userId: integer("user_id").references(() => users.id),
    metadata: jsonb("metadata"),
});

// Missing the relation between users and profileInfo. 
// Even though drizzle generated the reference correctly.

It would be useful if drizzle-kit could infer and generate the relations based on foreign key references. This approach is used by other frameworks https://www.prisma.io/docs/concepts/components/introspection#relations

The generated schema.ts should look like this.

import { pgTable, serial, text, integer, jsonb } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

export const users = pgTable('users', {
    id: serial('id').primaryKey(),
    name: text('name'),
});

export const profileInfo = pgTable('profile_info', {
    id: serial('id').primaryKey(),
    userId: integer("user_id").references(() => users.id),
    metadata: jsonb("metadata"),
});

// Auto generated the relation
export const usersProfileInfoRelations = relations(users, ({ one }) => ({
    profileInfo: one(profileInfo, {
        fields: [users.id],
        references: [profileInfo.userId],
    }),
}));
conanak99 commented 9 months ago

I think we can use the same approach as Prisma.

algora-pbc commented 7 months ago

πŸ’Ž $200 bounty created by @john-griffin πŸ‘‰ To claim this bounty, submit your pull request on Algora πŸ“ Before proceeding, please make sure you can receive payouts in your country πŸ’΅ Payment arrives in your account 2-5 days after the bounty is rewarded πŸ’― You keep 100% of the bounty award πŸ™ Thank you for contributing to drizzle-team/drizzle-kit-mirror!

Kartik1397 commented 7 months ago

/attempt #202

evoxf1 commented 7 months ago

/attempt #202

Kartik1397 commented 6 months ago

Hi @AndriiSherman, is drizzle-kit closed source? If it is closed source then is there any way I contribute to this issue?

xsjcTony commented 4 months ago

+1. Surprisingly this is not included in the introspect by default. Relations is some kinds of primitives of relational DBs, that they should be included in introspecting.

smblee commented 3 months ago

+1

gmotta-dev commented 3 months ago
gmwill934 commented 2 months ago

+1

Scalahansolo commented 2 months ago

Y'all. The Drizzle team is actively working on this and will be in the upcoming release from what they've said in Discord. Just gotta be patient.

terion-name commented 1 week ago

However, the generated schema.ts only contains the declaration for each table. Example:

import { pgTable, serial, text, integer, jsonb } from 'drizzle-orm/pg-core';
import { relations } from 'drizzle-orm';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name'),
});

export const profileInfo = pgTable('profile_info', {
  id: serial('id').primaryKey(),
  userId: integer("user_id").references(() => users.id),
  metadata: jsonb("metadata"),
});

// Missing the relation between users and profileInfo. 
// Even though drizzle generated the reference correctly.

Currently it doesn't even add .references() in table schema.

For example I have in db:

create table "public"."test2" (
    "id" bigint generated by default as identity not null,
    "created_at" timestamp with time zone not null default now(),
    "test_id" bigint
);

alter table "public"."test2" enable row level security;

CREATE UNIQUE INDEX test2_pkey ON public.test2 USING btree (id);

alter table "public"."test2" add constraint "test2_pkey" PRIMARY KEY using index "test2_pkey";

# foreign key!
alter table "public"."test2" add constraint "public_test2_test_id_fkey" FOREIGN KEY (test_id) REFERENCES test(id) not valid;

alter table "public"."test2" validate constraint "public_test2_test_id_fkey";

But introspected result:

export const test2 = pgTable("test2", {
    // You can use { mode: "bigint" } if numbers are exceeding js number limitations
    id: bigint("id", { mode: "number" }).notNull(),
    created_at: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(),
    // You can use { mode: "bigint" } if numbers are exceeding js number limitations
    test_id: bigint("test_id", { mode: "number" }), // <-------- has no reference !!!!
});

and log:

Using 'postgres' driver for database querying
[βœ“] 2  tables fetched
[βœ“] 8  columns fetched
[βœ“] 10 enums fetched
[βœ“] 0  indexes fetched
[βœ“] 0  foreign keys fetched

0 indexes fetched and 0 foreign keys fetched while they are definetely there