drizzle-orm: [BUG]: design: working with dynamic schemas is practically impossible
What version of drizzle-orm are you using?
0.23.2
Describe the Bug
This is not might be re-labeled as and design/architecture flaw and let me know if I get it wrong but: Imagine the typical multi-tenant app having a separate schema for each customer account - in this case drizzleorm is practically impossible to use since the whole API design revolves around directly including the schema TS code that is static by definition.
I would imagine something like this:
// schema definition
const accountSchema = pgDynamicSchema('account'); // instead of pgSchema, where the string param is just an optional prefix
export const users = accountSchema.table("users", {
//...
}
// some rest endpoint
const currentUserSchema = 'customer_schema_name'
db.select().from(users(currentUserSchema)) // this would then access "account_customer_schema_name" schema
But I understand this might mean to rewrite the whole thing…
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 8
- Comments: 24 (3 by maintainers)
Perhaps it would be beneficial to add the support for the second argument in the
fromfunction, like so:This modification would also enable the utilization of the placeholder feature in the following manner:
It seems that this aligns with the SQL approach that Drizzle aims to adhere to, as per the documentation. What are your thoughts on this suggestion?
@dankochetov We are using the function you suggested to dynamically create the schema and it works great for querying. We are however unsure how we would use drizzle-kit to generate sql migrations for the schema if it is defined within the function. Executing
drizzle-kit generate:pgtells us it didn’t find any Tables and that there is nothing to migrate. We need to have the dynamic schema at runtime because we have n-Tenants that we do not know at compile time, do you have a suggestion on how we could generate the Migrations?I am currently employing the following workaround:
I find this approach to be more DX-friendly and memory-efficient, especially in the case of a large number of identical schemas, compared to the use of
pgSchema:The only caveat is that
useDynamicSchemamust always be used for the same table once it has been applied.Additionally, this method facilitates easy migration to an official solution, once supported, by simply replacing
useDynamicSchema\(([^)]+)\)with$1. For example:Got it. It’s kindof annoying with the code duplication. It would be nice to just be able to attach the
usertable directly to the schema factory that way we could just define the table once instead of defining the columns and a schemaless table, then attach the table in the factory. Something like this:@mppub I’m a bit confused. Initially you said that you need to put the tables into different schemas for different customers, but the solution you came up with in the last message uses a dynamic prefix instead of a dynamic schema. If you need the dynamic schema, you can create a factory like this:
I’ve tested this locally, and it turned out current types are a bit misconfigured for this function to work, so I’ve pushed a fix to
drizzle-orm@beta. You can update and try it.Regarding the performance - I doubt there will be any noticeable issues using this method. You can test the performance by comparing the response times between using a table with a static schema and using a table factory.