Conditional findFirst

Is it possible to conditionally use findFirst, rather than having to chain the underlying model. E.g.
const result = await db.query.users.findMany({
with: {
posts: true
},
});
const result = await db.query.users.findMany({
with: {
posts: true
},
});
Into either:
const result = await db.query(users).findMany({
with: {
posts: true
},
});

OR

const result = await db.query[modelName]findMany({
with: {
posts: true
},
});
const result = await db.query(users).findMany({
with: {
posts: true
},
});

OR

const result = await db.query[modelName]findMany({
with: {
posts: true
},
});
17 Replies
Angelelz
Angelelz15mo ago
I'm not sure I quite understand what you're trying to acomplish. Do you want the table you're querying to be dynamic? You definitely do the second one. You can actually get your model types with
type ModelName = typeof db.query;
const getModelWithPosts = async (modelName: ModelName) => {
return await db.query[modelName].findFirst({
with: {posts: true}
});
}
// use it like this:
const userWithPosts = await getModelWithPosts("users");
type ModelName = typeof db.query;
const getModelWithPosts = async (modelName: ModelName) => {
return await db.query[modelName].findFirst({
with: {posts: true}
});
}
// use it like this:
const userWithPosts = await getModelWithPosts("users");
I'm not sure if that's what you're looking for.
Aidan Laycock
Aidan Laycock15mo ago
I believe that should solve it thank you! We've just created a wrapper shorthand for some of the consistent query types we do, so we're just looking at adding things like this so that we can streamline our development.
dew
dew15mo ago
Thanks for the snippet. Im trying to achieve similar result as Aidan, but using your example I couldn't get it to work. It's showing "type { ... RelationalQueryBuilder<MySql2PreparedQueryHKT, Extract.... } cannot be used as an index type"
NinjaBunny
NinjaBunny14mo ago
did you find a solution to this? I'm trying to implement the same thing, but I get that error as well
dew
dew14mo ago
No I didn’t 😞 If you did find out please let me know!
NinjaBunny
NinjaBunny14mo ago
I'll see if I can solve this solutiona nd share my findings
Angelelz
Angelelz14mo ago
drizzle have several type helpers for this type of stuff Can you show a code snippet of what you're trying to accomplish?
NinjaBunny
NinjaBunny14mo ago
import { Database } from "@modules/drizzle";
import { Injectable } from "@nestjs/common";
import { PgUpdateSetSource, PgTable, AnyPgColumn } from "drizzle-orm/pg-core";
import {
TableConfig,
InferInsertModel,
SelectedFields,
} from "drizzle-orm";

@Injectable()
export abstract class CrudService<
Table extends PgTable,
Id extends keyof Table["$inferSelect"],
> {
protected constructor(
private readonly table: Table,
private readonly pk: Id,
private readonly db: Database,
private model typeof db.query,
) {}

async findById(id: Id) {
return await this.db.query[<dynamic key>].findFirst({});
// ^? => I want this.model to be inserted here
}
}
import { Database } from "@modules/drizzle";
import { Injectable } from "@nestjs/common";
import { PgUpdateSetSource, PgTable, AnyPgColumn } from "drizzle-orm/pg-core";
import {
TableConfig,
InferInsertModel,
SelectedFields,
} from "drizzle-orm";

@Injectable()
export abstract class CrudService<
Table extends PgTable,
Id extends keyof Table["$inferSelect"],
> {
protected constructor(
private readonly table: Table,
private readonly pk: Id,
private readonly db: Database,
private model typeof db.query,
) {}

async findById(id: Id) {
return await this.db.query[<dynamic key>].findFirst({});
// ^? => I want this.model to be inserted here
}
}
however when I hover over model, it is of type readonly ... table, and this.db.query will no accept a readonly type
//acceptable
return await this.db.query["users"].findFirst({});

//not acceptable due to this.model being a readonly property
//honestly just need a way to grab all Table names or extract the Table name
return await this.db.query[this.model[Table["_"]["name"]].findFirst({});
//acceptable
return await this.db.query["users"].findFirst({});

//not acceptable due to this.model being a readonly property
//honestly just need a way to grab all Table names or extract the Table name
return await this.db.query[this.model[Table["_"]["name"]].findFirst({});
this is the iceberg of the error
Type '{ readonly applications: RelationalQueryBuilder<ExtractTablesWithRelations<typeof
Type '{ readonly applications: RelationalQueryBuilder<ExtractTablesWithRelations<typeof
and it just spits out the entire table I was thinking of doing this in the instantiation of the class like this
@Injectable()
export abstract class CrudService<
Table extends PgTable,
Id extends keyof Table["$inferSelect"],
//change
Name = Table["_"]["name"]
> {
protected constructor(
private readonly table: Table,
private readonly pk: Id,
private readonly db: Database,
//change
private readonly name: Name,
) {}

async findById(id: Id) {
return await this.db.query[this.name].findFirst({});
// ^? => string and not the string value of the actual table
}
}
@Injectable()
export abstract class CrudService<
Table extends PgTable,
Id extends keyof Table["$inferSelect"],
//change
Name = Table["_"]["name"]
> {
protected constructor(
private readonly table: Table,
private readonly pk: Id,
private readonly db: Database,
//change
private readonly name: Name,
) {}

async findById(id: Id) {
return await this.db.query[this.name].findFirst({});
// ^? => string and not the string value of the actual table
}
}
Angelelz
Angelelz14mo ago
This is very similar to this other question. He implemented this exact thing https://discordapp.com/channels/1043890932593987624/1148695514821435443 I think if you type private readonly name: typeof db.query, you should be good to go
NinjaBunny
NinjaBunny14mo ago
I don't think this is the right thread seems like a different issue also no typing it as private readonly doesn't work because the query itself won't work
NinjaBunny
NinjaBunny14mo ago
ahhh I saw that one, but the issue in particular is coming from the this.db.query, which is something that thread/other person had not implemented yet, and I was trying to implement that specific aspect
Angelelz
Angelelz14mo ago
Can you try typing name like this private readonly name: keyof typeof db.query
NinjaBunny
NinjaBunny14mo ago
I think I already tried that and ran into a similar issue that being this error blob which I have no idea what it means
This expression is not callable.
Each member of the union type '(<TConfig extends DBQueryConfig<"many", true, ExtractTablesWithRelations<typeof //continues to print the entire table
This expression is not callable.
Each member of the union type '(<TConfig extends DBQueryConfig<"many", true, ExtractTablesWithRelations<typeof //continues to print the entire table
async findById(id: Id) {
return await this.db.query[this.model].findMany({
});
async findById(id: Id) {
return await this.db.query[this.model].findMany({
});
chessterfi3ld
chessterfi3ld6mo ago
Same thing here, did someone find a solution ?
chessterfi3ld
chessterfi3ld6mo ago
a simple reproduction, get the TS error with two tables
No description
chessterfi3ld
chessterfi3ld6mo ago
No error with one table only
No description
Want results from more Discord servers?
Add your server