help with column builder types
As I play around with learning drizzle, I wondered if I could generate a drizzle schema from a master schema. I'm very close to being able to do that. As you can see in this repo I created: https://github.com/rizen/drizzle-icing/blob/main/user.ts
The code works perfectly, but problem is that when I try to use
InferModel
to get the column types from my schema, I'm getting
Where the I would get the following on a hand-built table:
My guess is that the problem lies in the use of the AnyMySqlColumnBuilder
type in this function:
Any help on what I should do to get the appropriate types out for InferModel
?GitHub
drizzle-icing/user.ts at main ยท rizen/drizzle-icing
A test trying to generate drizzle schemas from a master schema. - drizzle-icing/user.ts at main ยท rizen/drizzle-icing
39 Replies
You'd need to use generics for
makeTable
Otherwise there's nothing to infer from
You can check out the signature of mysqlTable
function in the ORM source for inspirationGitHub
drizzle-orm/table.ts at main ยท drizzle-team/drizzle-orm
TypeScript ORM for SQL. Contribute to drizzle-team/drizzle-orm development by creating an account on GitHub.
I know what generics are, but given that I don't pass anything in to
mysqlTable< HERE >()
I don't see how they could help in this circumstance for my own makeTable
function.
Any further hints you might be able to provide me?InferModel
needs those generics to infer the actual model from the table. If you're passing just a Record of columns to the table, InferModel won't be able to infer the actual column names and types from it.I get that, I just don't know enough about inference to know how to apply that to this code.
Is there any way I could hire you or your firm to make this work for me?
It's certainly possible! Let me discuss it with the team and come back tomorrow with more details (it's night in here currently).
Sounds good. Thanks for the consideration.
Hey @plainblackguy, we've set up the sponsorship page on GitHub, check out Silver and Gold tiers which include consultancy hours.
https://github.com/sponsors/drizzle-team
Sweet, and which level do I need for this project?
I'd estimate it in 1-3 hours. You can start with the silver tier.
I'm gonna go with the gold, because I'm certain I'll have more questions that I'll need your help with.
Ok, paid. How do we get started?
Thank you! You now have access to #gold-sponsors channel.
Please let me know:
1. If you want us to shoutout about your sponsorship? In that case, please provide your Twitter handle.
2. If you need this to be live sessions or simply for us to implement your task. For live sessions, I will provide a Calendly link in the #gold-sponsors channel.
1. feel free. my twitter handle is @plainblackguy, but my company, the one paying for this is @thegamecrafter
2. for right now, i'd just love to have the answer of how to do this, don't need a live session
@plainblackguy could you explain your use case a bit? Do you want to generate schemas in multiple ORMs from a single source? Have you finalized your "master schema" format, or is it a potential subject for change?
happy to explain
my schema will be in a single database: mysql specifically for this project
i've finalized my master schema as much as anything is ever final
the types look like
that's the types for creating the schema
the implementation of 1 table looks like this:
and the makeTable function looks like this:
all of that is "a lot"
so that's why i simplified it for you at the start of this thread
here's an example of one of the "db" helper functions that is generating your schema for an individual field type:
let me know if you need more, or if that was already too much and you need something simplified
OK, I see. The thing is, the types you've created don't have enough type information to be correctly inferred into a Drizzle table. Your tables don't type have information about specific columns, only the type for all the columns in general.
To make it clearer, what currently can be inferred from your schema is "in a
userSchema
, every column is either a string, an enum, a boolean etc. and has a name which is a string", but you cannot infer information like "userSchema is a table with a 'username' column of type string, an 'email' column of type string etc.", and that's the information that's required to create a Drizzle table. In other words, you have runtime data but no type data in your schemas.
If you want to be able to infer type information about specific columns and other things (like the table name), all that information need to be stored on type level, i.e. in generics.
That's why I asked if your schema format is final.ok...so reading between the lines a bit, i think you are saying what i want is impossible
i'm not opposed to changing my schema if needed
another option is that i could potentially use my schema to generate your hand written table.ts files
You mean via the codegen?
yeah
That's also an option, yes
If that's fine for you, it will be actually easier than building all the generic types required for this to work on type level
i don't like having the extra step, but if it means that i can write 1 schema to rule them all, and still use drizzle, then i'm fine doing that
i really like drizzle, even though it might not seem like it sometimes when i'm grilling you for answers
and again, i spent the past 6 weeks trying out over a dozen ORMs, so i know what's on the market
you've got something really cool here
All good, happy to help!
Thank you for your support ๐ช
So as a summary: you'd either need your schema types augmented with generics to store the type information about the columns and the table name, or use codegen to generate the Drizzle tables using its native syntax.
let me ask 1 question, before i go off and write the code gen step
can you give me a brief example of what the generics might look like. obviously i'd have to apply that through-out, but is it possible to give me a peek behind the curtain?
i just want to make sure that code gen is the best way to go, and that i'm not missing something
Yes, I can do that. I'll use the file you provided as a reference.
thanks
@plainblackguy there you go: https://github.com/rizen/drizzle-icing/pull/1
Also had to change the props from array to a map, because I wasn't able to easily figure out how to properly infer the array as a tuple
thank you
also....wow
yeah, code gen is going to be way cleaner
and easier
this pretty much exposes everything i hate about typescript
Same
Type syntax in TypeScript is god awful
probably code gen will be easier for people to understand also, cuz ultimately the file they get will look like what you show them in your docs
not to mention, when i need to come bug you for a a solution to a problem, i can just give you my table definition without having to unwrap it from my schema ๐
thanks again for all your help
I mean, it's always good to learn advanced TypeScript patterns
But yeah, in a long run it will be easier
We made the ORM without the codegen not because it's simple, but because we thought it's simple we know TypeScript to the point when we can implement what we need without codegen
The types we had to build are crazy hard
i'm certain of that...just using types is hard in a lot of cases, i can't even imagine trying to build something as complex as this as you have
sleep well, and have a good weekend. from my point of view you've earned it
Thanks!
You too
and code generation complete!
looks like it was hand written
Amazing!
thanks for your help
@plainblackguy looks great! what did you use for code-gen? was it TS server API, or just string concatenations?
Just template strings.
got it