-
-
Notifications
You must be signed in to change notification settings - Fork 736
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
Feat: Drizzle-ORM support for Generated columns #1471
Feat: Drizzle-ORM support for Generated columns #1471
Conversation
…ll Pg column builders and fixed types
…rs and fixed types
…intergration tests
870b55a
to
6061a63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
However, you should probably get rid of the merge commit and the comments that I highlighted in the comments below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super, let's merge this!
This will also close #1239 |
Any updates on this? Thank you! |
@Angelelz could you please show how this feature infers select or insert types for "generated always as identity" columns? It should forbid the user to insert values to a column of this type because postgres will always throw an error. type NewUser = typeof users.$inferInsert;
// ^? {
// email: string;
// firstName?: string | null | undefined;
// lastName?: string | null | undefined;
// }, or be type NewUser = typeof users.$inferInsert;
// ^? {
// email: string;
// id: never;
// firstName?: string | null | undefined;
// lastName?: string | null | undefined;
// }, |
This looks awesome! What's holding up merging this PR? Generated columns are currently very difficult, because of the custom type bug in drizzle-kit https://github.com/drizzle-team/drizzle-kit-mirror/issues/167. |
Is there anything the community can do to help this move forward? It's currently kind of cumbersome to create a custom type every time we need a generated column and this feature would make schema declarations much cleaner imho. |
Echoing the comments above on how we can help move this PR forward -- I think this PR adds some fairly necessary functionality! |
Hi! Thanks for this PR! Exactly what I was looking for :) I just made a fork of this change to try it out and installed it as an override for I tried it using it with sqlite, mysql and postgres, but unfortunately I was not able to get it to work. Here's the small test model I used for sqlite. const urnPrefix = "urn:example:users:";
export const usersTable = sqliteTable("users", {
id: integer("id").unique().notNull().primaryKey({ autoIncrement: true }),
urn: text("urn").generatedAlwaysAs(sql`${urnPrefix} || id`, { mode: "virtual" }).notNull().unique(),
}); I ran Is this meant to work with drizzle-kit or will this require a separate change? I played around with it a bit more and I came up with the following solution that does work for me: export interface GenerateCustomTypeOptions<T> {
data: T;
config: { sql: SQL | string; mode?: "stored" | "virtual" | undefined };
notNull: true;
default: true;
configRequired: true;
}
export type GeneratedColumnType = <T>(
...args: Parameters<ReturnType<typeof customType<GenerateCustomTypeOptions<T>>>>
) => ReturnType<ReturnType<typeof customType<GenerateCustomTypeOptions<T>>>>;
const generated: GeneratedColumnType = <T>(
...args: Parameters<ReturnType<typeof customType<GenerateCustomTypeOptions<T>>>>
) => {
const [_, config] = args;
const asSql = sql`as (${config.sql})`;
const asSqlString = asSql.toQuery({
escapeName: (name) => `'${name}`,
escapeParam: (_, value) => `'${value}'`,
escapeString: (str) => `'${str}'`,
}).sql;
const joinedSqlString = `${asSqlString} ${config?.mode ?? "virtual"}`;
return customType<GenerateCustomTypeOptions<T>>({
dataType: () => joinedSqlString,
})(...args).generatedAlwaysAs(asSql, { mode: config.mode });
}; Note: The Do you think it would make sense to adapt this PR to provide a |
It is time to ditch the PostgreSQL specific way of doing auto incremented columns with SERIAL. |
Maybe, in the meantime, leave an example in the docs with the necessary SQL code to make this happen? |
The catch is that there's currently no way to implement this using a custom type in a manner that is compatible with drizzle-kit (#579 (comment)). So adding the workaround in the docs might just end up confusing more users who are going to face failing migrations. |
For Postgres users here is a diff --git a/node_modules/drizzle-kit/bin.cjs b/node_modules/drizzle-kit/bin.cjs
index 9b92321..d347342 100755
--- a/node_modules/drizzle-kit/bin.cjs
+++ b/node_modules/drizzle-kit/bin.cjs
@@ -15496,6 +15496,7 @@ var init_sqlgenerator = __esm({
"interval minute to second"
]);
isPgNativeType = (it) => {
+ return true
if (pgNativeTypes.has(it))
return true;
const toCheck = it.replace(/ /g, "");
I've only tested this type, test other custom types as I have no clue if this will break them import { customType } from "drizzle-orm/pg-core";
export const identity = (name: string) =>
customType<{
data: string;
notNull: true;
default: true;
}>({
dataType() {
return "BIGINT GENERATED ALWAYS AS IDENTITY";
},
})(name); |
Heya, thanks a lot for amazing work! |
Adding a +1 for this - would love to use generated columns for post comment counts and such! It would get widespread use throughout the app I'm building. 🙏 😁 |
+1 for this! |
+1 for this, would be great for generated columns in fulltext search for types like arrays with tags for example! |
Back in March it sounded like this PR was set to be merged, and then progress stalled. I can't find the discussion now, but I remember reading in Discord that the Drizzle team was going to make some major changes to schema definition implying that it would require a different approach for generated columns. (Maybe this? #2316) So I wouldn't expect this PR to get merged soon. Personally, after waiting several months for generated columns I couldn't wait any longer. Text and location search are a vital part of my project. I ended up ripping Drizzle out of everything, and just using the Postgres.js driver directly. Which also solved a lot of other issues (e.g. lack of query aggregations, a bug in migration generation for custom types, etc.). It turns out that writing my own TS type definitions was easier than I expected. Not trying to bash Drizzle. It's excellent. It's just missing some features that I need right now. |
sending this to beta release today, I'm finishing release notes, will update here |
Release notes with all the detailed info: https://github.com/drizzle-team/drizzle-orm/releases/tag/v0.32.0-beta GitHub discussions: #2564 |
This PR will close #261, will close #579 and will close #1464.
The API for generated columns will look like this:
In Postgres there is also a new method on
integer
bigint
andsmallint
columns called.generatedAsIdentity()
You can pass a configuration object that will be different depending on your dialect:
For this table, the inferred types will be as follows:
Please note that drizzle kit support for this is still pending.