drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.81k stars 658 forks source link

[BUG]: Wrapping a pg client in drizzle affects query response of other clients #1991

Open Zevgon opened 8 months ago

Zevgon commented 8 months ago

What version of drizzle-orm are you using?

0.30.1

What version of drizzle-kit are you using?

0.20.14

Describe the Bug

In the following snippet, the 2 query responses are different, even though the client and the query are the same.

import { drizzle } from 'drizzle-orm/node-postgres';
import { Client } from 'pg';

(async () => {
    const vanillaClient = new Client({
        user: myConfig.username,
        host: myConfig.proxy,
        database: myConfig.dbname,
        password: myConfig.password,
        port: myConfig.port,
    });
    await vanillaClient.connect();

    // Set up
    await vanillaClient.query('BEGIN');
    await vanillaClient.query(
        "CREATE TABLE my_table (date_created timestamp DEFAULT NOW(), my_interval interval DEFAULT '1 year')"
    );
    await vanillaClient.query('INSERT INTO my_table DEFAULT VALUES');

    // Query 1
    const query1Response = await vanillaClient.query('SELECT * FROM my_table');
    console.log('query1 typeof date_created:', typeof query1Response.rows[0].date_created); // query1 typeof date_created: object
    console.log('query1 my_interval:', query1Response.rows[0].my_interval); // query1 my_interval: PostgresInterval { years: 1 }

    // Create a separate client and wrap it in drizzle
    drizzle(
        new Client({
            user: myConfig.username,
            host: myConfig.proxy,
            database: myConfig.dbname,
            password: myConfig.password,
            port: myConfig.port,
        })
    );

    // Query 2, identical to query 1 and still using the vanilla client instance, but different response now
    const query2Response = await vanillaClient.query('SELECT * FROM my_table');
    console.log('query2 typeof date_created:', typeof query2Response.rows[0].date_created); // query2 typeof date_created: string
    console.log('query2 my_interval:', query2Response.rows[0].my_interval); // query2 my_interval: 1 year

    // Tear down
    await vanillaClient.query('DROP TABLE my_table');
    await vanillaClient.query('COMMIT');
})();

It looks like this is because the NodePgDriver.initMappers method sets the type parsers globally, instead of setting them just for the client. I verified that this can be fixed by using this.client.setTypeParser instead of using the imported types, although I'm not sure what all the implications of that are.

Drizzle looks crazily cool but this bug is a hard blocker for our team.

Expected behavior

Wrapping one client in drizzle should not affect the behavior of other clients.

Environment & setup

No response

antoncazalet commented 8 months ago

Hello ! I had the same issue while using two ORM's in the same server. I had to create patch to disable the types parser and handle it myself. Would love to see this issue resolved. Many thanks !

L-Mario564 commented 1 month ago

Drizzle changes the global mappings of certain data types when initializing the DB instance.