electric-sql / pglite

Lightweight WASM Postgres with real-time, reactive bindings.
https://pglite.dev
Apache License 2.0
9.45k stars 204 forks source link

Drizzle's relational query builder not working with worker #396

Closed bastiankistner closed 1 month ago

bastiankistner commented 1 month ago

I've setup pglite with idb and alternatively with opfs-ahp/worker and drizzle. Usually there should be a .query.* available for the drizzle client when you pass in the schema as secondary options argument, which is the case for indexeddb. But it's empty, when I initialize it with the worker.

This is my worker

import { PGlite } from '@electric-sql/pglite';
import { live } from '@electric-sql/pglite/live';
import { OpfsAhpFS } from '@electric-sql/pglite/opfs-ahp';
import { worker } from '@electric-sql/pglite/worker';

await worker({
    async init() {
        return await PGlite.create({
            extensions: { live },
            fs: new OpfsAhpFS('/dummy/abc'),
        });
    },
});

and this is the code for the client

import * as schema from '@/drizzle/pglite';
import { PGliteWorker } from '@electric-sql/pglite/worker';
import { drizzle } from 'drizzle-orm/pglite';
import { live } from '@electric-sql/pglite/live';

const pg = await PGliteWorker.create(
    new Worker(new URL('./worker/index.ts', import.meta.url), {
        type: 'module',
    }),
    {
        extensions: {
            live,
        },
    },
);

// @ts-expect-error should work
const db = drizzle(pg, { schema });

Then, later on

console.log(db.query) // empty object

however, when I use the indexeddb version

import { IdbFs, PGlite } from '@electric-sql/pglite';
import { live } from '@electric-sql/pglite/live';

const pgIdb = await PGlite.create({
    extensions: { live },
    fs: new IdbFs('pglite-db'),
});

const dbIdb = drizzle(pgIdb, { schema: dt });

// and later

console.log(dbIdb.query) // this contains my schema tables

query is properly set to reflect my schema.

Am I missing something or is this not supposed to work?

below is a screenshot of a console log where it's also obvious that the schema was not set

image
samwillis commented 1 month ago

I would expect that to work. Is the PGliteWorker instance working in your setup without going via Drizzle?

bastiankistner commented 1 month ago

Just tested the following so far without the querybuilder and it returns data (but haven't tested with plain sql and no drizzle yet)

await db.insert(dt.orders).values({ raw: { orderId: '123456' } });
const orderOpfs = await db.select().from(dt.orders).limit(10);

But I also tried debugging the worker. The init method does not seem to be called and the only tab I have open tells me that it's not the leader.

Maybe something is wrong with my setup.

I think I'll give it a shot in a plain starter project tomorrow and see if it works. I somehow have the feeling that this issue is not related to pglite. I'll let you know!

bastiankistner commented 1 month ago

I figured out what the issue was: drizzle-orm@0.35.1, which was released 2 days ago and obviously had some bugs in it.

They released a fix 6 hours ago and since then it works as expected.

Here's a link to the release notes for 0.35.2 : https://github.com/drizzle-team/drizzle-orm/releases/tag/0.35.2

Sorry for taking your time! It did look like an issue with pglite because the non-worker version was exposing the query attribute properly.