node.js - Hur lägger man till "FETCH FIRST n ROWS ONLY" med Kysely DB-frågebuilder?
Mitt favoritverktyg för databaser att använda med TypeScript-baserade projekt är Prisma. Dock använder ett av projekten Kysely, en typ-säker databasfrågebyggare.
Jag försöker förbereda en fråga som skulle hantera keyset-paginering med Kysely query builder, men jag kan inte lista ut hur man lägger till FETCH FIRST n ROWS ONLY i frågan om det ens är möjligt.
Kysely-dokumentation: https://kysely.dev/docs/category/select
Några idéer eller förslag?
import { Kysely, sql } from "kysely";
const DB = new Kysely<Database>({...});
const query = DB
.selectFrom("cl")
.selectAll()
.where(sql`(created_at, id)`, '>', `('${keyFromCreatedAt}', '${keyFromId}')`)
// ¿¿¿ Something to insert FETCH FIRST n ROWS ONLY? ???
;
const res = query.execute();
Svar #1
För det första kan du använda LIMIT-klausulen (SelectQueryBuilder.limit(n)) som ett alternativ för FETCH FIRST n ROWS ONLY, beroende på vilken dialekt du använder. Om du måste använda FETCH FIRST n ENDAST RADER bör du implementera din egen QueryCompiler.
Det tar inte mycket tid. Allt är redan implementerat i DefaultQueryCompiler. Allt du behöver göra är att utöka det och åsidosätta en enskild metod. Till exempel åsidosätter PostgresQueryCompiler en enskild metod från DefaultQueryCompiler.
export class PostgresQueryCompiler extends DefaultQueryCompiler {
protected override sanitizeIdentifier(identifier: string): string {
return identifier.replace(ID_WRAP_REGEX, '""')
}
}
Definiera din anpassade QueryCompiler och åsidosätt visitLimit-metoden för att ändra beteendet hos limit().
class MyQueryCompiler extends PostgresQueryCompiler {
protected visitLimit(node: LimitNode) {
this.append("fetch next ")
this.visitNode(node.limit);
this.append(" rows only")
}
}
Sedan utökar en Dialect-klass och överskriver createQueryCompiler()-metoden för att använda QueryCompiler.
class MyDialect extends PostgresDialect {
createQueryCompiler(): QueryCompiler {
return new MyQueryCompiler();
}
}
Skicka det till Kysely-konstruktorn för att använda det.
const db = new Kysely<DB>({
dialect:new MyDialect(...),
})
PostgresQueryCompiler och PostgresDialect är bara exempel. Du kan åsidosätta vilken dialekt du vill.
Fullständigt exempel:
import {
Kysely, LimitNode,
PostgresDialect, PostgresQueryCompiler,
QueryCompiler
} from "kysely";
class MyQueryCompiler extends PostgresQueryCompiler {
protected visitLimit(node: LimitNode) {
this.append("fetch next ")
this.visitNode(node.limit);
this.append(" rows only")
}
}
class MyDialect extends PostgresDialect {
createQueryCompiler(): QueryCompiler {
return new MyQueryCompiler();
}
}
const db = new Kysely<any>({
dialect: new MyDialect({} as any),
})
const {sql} = db.selectFrom("table").select(["a", "b"]).limit(10).offset(20).compile()
console.log(sql) // select "a", "b" from "table" fetch next $1 rows only offset $2
