database connection doesn't work in / behave strangely in global context.

this doesn't work
const db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});

app.get("/", async (c) => {
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
const db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});

app.get("/", async (c) => {
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
this however does work fine.
app.get("/", async (c) => {
const db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
app.get("/", async (c) => {
const db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
both work fine in lambdas. what's happening ?
6 Replies
Hello, I’m Allie!
Workers does not allow I/O in global contexts. I would recommend doing something like the following if you must use global contexts:
let db: Kysely<DB>;

app.get("/", async (c) => {
if(!db) {
db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});
}
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
let db: Kysely<DB>;

app.get("/", async (c) => {
if(!db) {
db = new Kysely<DB>({
dialect: new PostgresDialect({ pool: new Pool({ connectionString }) }),
});
}
const langs = await db.selectFrom("Language").selectAll().executeTakeFirst();
return c.json(langs);
});
Ahmed Eid
Ahmed EidOP2mo ago
this unfortunately doesn't work either. it's weird, cuz one request works & the 2nd one doesn't...
Hello, I’m Allie!
Yeah, I would recommend just not using the global scope then While the above suggestion might work, it appears that Kysely may attempt to keep the connection open across multiple requests, which afaik doesn't work
Ahmed Eid
Ahmed EidOP2mo ago
I looked into hyperdrive ( still don't understand it fully .. ) do you think this is performant enough ?
type Env = {
Bindings: { db: Hyperdrive };
Variables: { db: Kysely<DB> };
};

export const databaseMiddleware = (): MiddlewareHandler =>
createMiddleware<Env>(async (c, next) => {
const hv = c.env.db;
const db = new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({ connectionString: hv.connectionString }),
}),
});
c.set("db", db);
await next();
});
type Env = {
Bindings: { db: Hyperdrive };
Variables: { db: Kysely<DB> };
};

export const databaseMiddleware = (): MiddlewareHandler =>
createMiddleware<Env>(async (c, next) => {
const hv = c.env.db;
const db = new Kysely<DB>({
dialect: new PostgresDialect({
pool: new Pool({ connectionString: hv.connectionString }),
}),
});
c.set("db", db);
await next();
});
Hello, I’m Allie!
That looks fine?
Ahmed Eid
Ahmed EidOP2mo ago
I think so, I am new to this TBH. I am still learning. I change it to this
export const databaseMiddleware = (): MiddlewareHandler =>
createMiddleware<Env>(async (c, next) => {
const hv = c.env.db;
const db = new Kysely<DB>({
dialect: new PostgresJSDialect({
postgres: postgres(hv.connectionString),
}),
});
const end = performance.now();
c.set("db", db);
await next();
});
export const databaseMiddleware = (): MiddlewareHandler =>
createMiddleware<Env>(async (c, next) => {
const hv = c.env.db;
const db = new Kysely<DB>({
dialect: new PostgresJSDialect({
postgres: postgres(hv.connectionString),
}),
});
const end = performance.now();
c.set("db", db);
await next();
});
Want results from more Discord servers?
Add your server