Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1 #1

Open
15 of 17 tasks
farreldarian opened this issue Dec 17, 2023 · 23 comments
Open
15 of 17 tasks

v1 #1

farreldarian opened this issue Dec 17, 2023 · 23 comments
Assignees

Comments

@farreldarian
Copy link
Owner

farreldarian commented Dec 17, 2023

Planned Features

These are the essential features needed for querying and mutating purposes, providing 1:1 feature mapping from Prisma. Please mention if there's anything missed from this list.

Models

  • Field types
    • Scalar
      • Unsupported
    • List
    • Relations (e.g. []) for Drizzle relational query
    • Enum
  • Constraints
    • ID
    • primaryKey
    • notNull (when no ? modifier)
  • Custom @db. field

Helpers

Config

  • Support for all providers
    • postgres
    • mysql
    • sqlite

Not planned

v1 will concentrates exclusively on query and mutation operations, these parts are currently not on consideration:

@farreldarian farreldarian self-assigned this Dec 17, 2023
@farreldarian farreldarian pinned this issue Dec 17, 2023
@LilaRest
Copy link

Following this 👀 Thanks for your work.

@octalpixel
Copy link

Amazing work! Looking forward to the SQLite support.

@farreldarian
Copy link
Owner Author

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

@octalpixel
Copy link

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

Thanks for the ping. Will check this out later today.

@octalpixel
Copy link

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

Thanks for the ping. Will check this out later today.

Hey tried this now on a quick sample project with two tables and it works well! Thanks for this! Will do a bit more a bigger schema.

@octalpixel
Copy link

I know this a bit unrela

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

Thanks for the ping. Will check this out later today.

Hey tried this now on a quick sample project with two tables and it works well! Thanks for this! Will do a bit more a bigger schema.

Ik this a bit unrelated but I tried this on React Native Project, and there is require cycle.
image

This because categories and transaction import each other for relationships.

How about an optional flag to define all the relationship in another file ?

@farreldarian
Copy link
Owner Author

I know this a bit unrela

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

Thanks for the ping. Will check this out later today.

Hey tried this now on a quick sample project with two tables and it works well! Thanks for this! Will do a bit more a bigger schema.

Ik this a bit unrelated but I tried this on React Native Project, and there is require cycle. image

This because categories and transaction import each other for relationships.

How about an optional flag to define all the relationship in another file ?

Thanks for noticing! Just released the patch v0.5.2 where you can add relationalQuery = false

generator drizzle {
  provider        = "prisma-generator-drizzle"
  relationalQuery = false
}

A proper fix would be to simply separate the definition to a separate file later

@octalpixel
Copy link

I know this a bit unrela

@octalpixel I've just added the SQLite adapter on v0.5.0, feel free to check out and let me know if there's a problem

Thanks for the ping. Will check this out later today.

Hey tried this now on a quick sample project with two tables and it works well! Thanks for this! Will do a bit more a bigger schema.

Ik this a bit unrelated but I tried this on React Native Project, and there is require cycle. image
This because categories and transaction import each other for relationships.
How about an optional flag to define all the relationship in another file ?

Thanks for noticing! Just released the patch v0.5.2 where you can add relationalQuery = false

generator drizzle {
  provider        = "prisma-generator-drizzle"
  relationalQuery = false
}

A proper fix would be to simply separate the definition to a separate file later

Thanks! I believe this is one way of solving it. Also just looking at your patch at the moment and train of thought.Maybe not the best, but here is a thought dump

  • Have a flag to output everything to one file. (Fixes the require cycle for React Native projects)
  • Have a flag to output relationship to another file
  • Flag to only generate relationships (This can actually be a good starting point to learn about how to make relationships with Drizzle as well)

@Scalahansolo
Copy link
Contributor

It would be great if this lib also properly handled @ignore and @@ignore. Basically don't pull these columns and/or tables into the generated schema(s).

@farreldarian
Copy link
Owner Author

It would be great if this lib also properly handled @ignore and @@ignore. Basically don't pull these columns and/or tables into the generated schema(s).

Yeah that seems simple.

@octalpixel
Copy link

So just wanted to report an experiment that I did. After trying out your lib, an idea sparked in my head. WHAT IF we introspect the database using drizzlekit to actually pull in the schema. I tried this with a local sqlite db, and db pushed the schema to it using prisma and introspected it with drizzlekit. This is what I got.

PS: Disregard the table names being title case :D

From introspect

export const transaction = sqliteTable("Transaction", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	amount: real("amount").notNull(),
	date: numeric("date").notNull(),
	description: text("description"),
	createdAt: numeric("createdAt").default(sql`(CURRENT_TIMESTAMP)`).notNull(),
	updatedAt: numeric("updatedAt").notNull(),
	transCategoryId: integer("transCategoryId").references(() => transCategory.id, { onDelete: "set null", onUpdate: "cascade" } ),
	categoryId: integer("categoryId").references(() => category.id, { onDelete: "set null", onUpdate: "cascade" } ),
});

export const transCategory = sqliteTable("TransCategory", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	name: text("name").notNull(),
},
(table) => {
	return {
		nameKey: uniqueIndex("TransCategory_name_key").on(table.name),
	}
});

From the generator

export const transactions = sqliteTable('Transaction', {
  id: integer('id', { mode: 'number' }).primaryKey(),
  amount: real('amount').notNull(),
  date: integer('date', { mode: 'timestamp' }).notNull(),
  description: text('description'),
  createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
  updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
  transCategoryId: integer('transCategoryId', { mode: 'number' }),
  categoryId: integer('categoryId', { mode: 'number' }),
});

export const transactionsRelations = relations(transactions, (helpers) => ({
  TransCategory: helpers.one(transCategories, {
    relationName: 'TransCategoryToTransaction',
    fields: [transactions.transCategoryId],
    references: [transCategories.id],
  }),
  Category: helpers.one(categories, {
    relationName: 'CategoryToTransaction',
    fields: [transactions.categoryId],
    references: [categories.id],
  }),
}));

Off scope for you: One thing I noticed that prisma doesn't play well with enum of sqlite (Probably something you can look into). If i remember correctly Sqlite enums are done using CHECKS in sql so in one way doesnt make sense ?

Also drizzle-team/drizzle-orm#636 seems to be solved with incorrect relationships. So I guess in theory the introspect should work ?

@farreldarian
Copy link
Owner Author

farreldarian commented Jan 3, 2024

So just wanted to report an experiment that I did. After trying out your lib, an idea sparked in my head. WHAT IF we introspect the database using drizzlekit to actually pull in the schema. I tried this with a local sqlite db, and db pushed the schema to it using prisma and introspected it with drizzlekit. This is what I got.

PS: Disregard the table names being title case :D

From introspect

export const transaction = sqliteTable("Transaction", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	amount: real("amount").notNull(),
	date: numeric("date").notNull(),
	description: text("description"),
	createdAt: numeric("createdAt").default(sql`(CURRENT_TIMESTAMP)`).notNull(),
	updatedAt: numeric("updatedAt").notNull(),
	transCategoryId: integer("transCategoryId").references(() => transCategory.id, { onDelete: "set null", onUpdate: "cascade" } ),
	categoryId: integer("categoryId").references(() => category.id, { onDelete: "set null", onUpdate: "cascade" } ),
});

export const transCategory = sqliteTable("TransCategory", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	name: text("name").notNull(),
},
(table) => {
	return {
		nameKey: uniqueIndex("TransCategory_name_key").on(table.name),
	}
});

From the generator

export const transactions = sqliteTable('Transaction', {
  id: integer('id', { mode: 'number' }).primaryKey(),
  amount: real('amount').notNull(),
  date: integer('date', { mode: 'timestamp' }).notNull(),
  description: text('description'),
  createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
  updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
  transCategoryId: integer('transCategoryId', { mode: 'number' }),
  categoryId: integer('categoryId', { mode: 'number' }),
});

export const transactionsRelations = relations(transactions, (helpers) => ({
  TransCategory: helpers.one(transCategories, {
    relationName: 'TransCategoryToTransaction',
    fields: [transactions.transCategoryId],
    references: [transCategories.id],
  }),
  Category: helpers.one(categories, {
    relationName: 'CategoryToTransaction',
    fields: [transactions.categoryId],
    references: [categories.id],
  }),
}));

Off scope for you: One thing I noticed that prisma doesn't play well with enum of sqlite (Probably something you can look into). If i remember correctly Sqlite enums are done using CHECKS in sql so in one way doesnt make sense ?

Also drizzle-team/drizzle-orm#636 seems to be solved with incorrect relationships. So I guess in theory the introspect should work ?

That's actually also my initial hack a while ago, and it is a good one! (depends on the stability of db pull tho)

However the downside for this solution is that it requires an active database connection, meaning it requires another setup and it became more complex when managing with multiple branches. Therefore since Prisma already have their DMMF helper, as well as other packages like the nexus, zod, typegraphql, pothos, etc.. uses this technique to map Prisma with their features, it'd be safer use the proven pipeline like the others.

Off scope for you: One thing I noticed that prisma doesn't play well with enum of sqlite (Probably something you can look into). If i remember correctly Sqlite enums are done using CHECKS in sql so in one way doesnt make sense ?

Fyi I'm not really familiar for this. Currently the goal of this library is to provide all features that Prisma has — excluding unsupported features like the ENUMs in sqlite. Once Prisma has the support, we could reliably map the feature to drizzle.

So if you'd like to use one that drizzle has already supported, I think you could generate and commit the result. However it requires you to maintain the modified schema everytime the script generates the schema, I think this could be a feature that we could look in the future.

Also I think this is where the db pull solution comes in, it's more of a subsidiary rather than complementary.

@octalpixel
Copy link

So just wanted to report an experiment that I did. After trying out your lib, an idea sparked in my head. WHAT IF we introspect the database using drizzlekit to actually pull in the schema. I tried this with a local sqlite db, and db pushed the schema to it using prisma and introspected it with drizzlekit. This is what I got.
PS: Disregard the table names being title case :D
From introspect

export const transaction = sqliteTable("Transaction", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	amount: real("amount").notNull(),
	date: numeric("date").notNull(),
	description: text("description"),
	createdAt: numeric("createdAt").default(sql`(CURRENT_TIMESTAMP)`).notNull(),
	updatedAt: numeric("updatedAt").notNull(),
	transCategoryId: integer("transCategoryId").references(() => transCategory.id, { onDelete: "set null", onUpdate: "cascade" } ),
	categoryId: integer("categoryId").references(() => category.id, { onDelete: "set null", onUpdate: "cascade" } ),
});

export const transCategory = sqliteTable("TransCategory", {
	id: integer("id").primaryKey({ autoIncrement: true }).notNull(),
	name: text("name").notNull(),
},
(table) => {
	return {
		nameKey: uniqueIndex("TransCategory_name_key").on(table.name),
	}
});

From the generator

export const transactions = sqliteTable('Transaction', {
  id: integer('id', { mode: 'number' }).primaryKey(),
  amount: real('amount').notNull(),
  date: integer('date', { mode: 'timestamp' }).notNull(),
  description: text('description'),
  createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),
  updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),
  transCategoryId: integer('transCategoryId', { mode: 'number' }),
  categoryId: integer('categoryId', { mode: 'number' }),
});

export const transactionsRelations = relations(transactions, (helpers) => ({
  TransCategory: helpers.one(transCategories, {
    relationName: 'TransCategoryToTransaction',
    fields: [transactions.transCategoryId],
    references: [transCategories.id],
  }),
  Category: helpers.one(categories, {
    relationName: 'CategoryToTransaction',
    fields: [transactions.categoryId],
    references: [categories.id],
  }),
}));

Off scope for you: One thing I noticed that prisma doesn't play well with enum of sqlite (Probably something you can look into). If i remember correctly Sqlite enums are done using CHECKS in sql so in one way doesnt make sense ?
Also drizzle-team/drizzle-orm#636 seems to be solved with incorrect relationships. So I guess in theory the introspect should work ?

That's actually also my initial hack a while ago, and it is a good one! (depends on the stability of db pull tho)

However the downside for this solution is that it requires an active database connection, meaning it requires another setup and it became more complex when managing with multiple branches. Therefore since Prisma already have their DMMF helper, as well as other packages like the nexus, zod, typegraphql, pothos, etc.. uses this technique to map Prisma with their features, it'd be safer use the proven pipeline like the others.

Off scope for you: One thing I noticed that prisma doesn't play well with enum of sqlite (Probably something you can look into). If i remember correctly Sqlite enums are done using CHECKS in sql so in one way doesnt make sense ?

Fyi I'm not really familiar for this. Currently the goal of this library is to provide all features that Prisma has — excluding unsupported features like the ENUMs in sqlite. Once Prisma has the support, we could reliably map the feature to drizzle.

So if you'd like to use one that drizzle has already supported, I think you could generate and commit the result. However it requires you to maintain the modified schema everytime the script generates the schema, I think this could be a feature that we could look in the future.

Also I think this is where the db pull solution comes in, it's more of a subsidiary rather than complementary.

Definitely! Thanks for your insights on this! I empathize with the fact that extra setup is needed for a case like such. My thought process if purely SQLite based. Thats where your libs value prop lies for me. Really love what Prisma Schema has to offer for the DX when setting up the database. Looking to use Prisma as the schema generator, more sort of like where some devs use Prisma + Kysely.

@farreldarian
Copy link
Owner Author

Definitely! Thanks for your insights on this! I empathize with the fact that extra setup is needed for a case like such. My thought process if purely SQLite based. Thats where your libs value prop lies for me. Really love what Prisma Schema has to offer for the DX when setting up the database. Looking to use Prisma as the schema generator, more sort of like where some devs use Prisma + Kysely.

Thanks also for the suggestion! keep it coming

@octalpixel
Copy link

Definitely! Thanks for your insights on this! I empathize with the fact that extra setup is needed for a case like such. My thought process if purely SQLite based. Thats where your libs value prop lies for me. Really love what Prisma Schema has to offer for the DX when setting up the database. Looking to use Prisma as the schema generator, more sort of like where some devs use Prisma + Kysely.

Thanks also for the suggestion! keep it coming

Also! I forgot to mention you have another value prop. You generate the relationships as well where the introspect does not drizzle-team/drizzle-kit-mirror#202

@jakubczarnowski
Copy link

Hi! Are default values currently in development? I'd want to use the package, but unfortunately default values of identifiers aren't set properly, so typescript wants me to set ID on every insert, kinda annoying!

@farreldarian
Copy link
Owner Author

Hi! Are default values currently in development? I'd want to use the package, but unfortunately default values of identifiers aren't set properly, so typescript wants me to set ID on every insert, kinda annoying!

On it #22

@Scalahansolo
Copy link
Contributor

Hey @farreldarian with the inclusion of defaults support, could you push a new version?

@farreldarian
Copy link
Owner Author

farreldarian commented Jan 20, 2024

I'm planning to address #18 and add bytes support for the 0.6.0, but I've just published a canary release If you'd like to try out

@jakubczarnowski
Copy link

Hi, this works great with general default values, but unfourtenately this didn't solve the id issues.
Ids are generated like this based on my postgres db:
id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
Current implementation doesn't really work in this case, only with autoincrement. Is there something you could do? @farreldarian

@farreldarian
Copy link
Owner Author

farreldarian commented Jan 20, 2024

Hi, this works great with general default values, but unfourtenately this didn't solve the id issues. Ids are generated like this based on my postgres db: id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid Current implementation doesn't really work in this case, only with autoincrement. Is there something you could do? @farreldarian

Defining dbgenerated explicitly will work, I'm working on the PR right know. But I couldn't find in the prisma docs defining the mapping for uuid() function in SQL for each provider.

In this case I recommend using the drizzle.default directive to generate via javascript, similar to what Prisma does with cuid().

UPDATE
It's all generated by the prisma engine, including uuid().

@jakubczarnowski
Copy link

Looks great! Could you provide a canary version for now to test it out? Thanks!

@farreldarian
Copy link
Owner Author

Looks great! Could you provide a canary version for now to test it out? Thanks!

Just released v0.6.0 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants