-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concurrent inserts with json result in some being written in string format #937
Comments
don't use sql.json, it's deprecated and only for very specific cases |
What's the correct way to insert into a jsonb field using template syntax? Option 1: sql.jsonWhat I was doing, due to issues like #838 Not deprecated: ❌ Option 2: Directly const jsonReady = {
foo: "bar",
};
const obj =
await sql`INSERT INTO dodgy_json(dodgy) VALUES (${jsonReady}) RETURNING id;`; fails with:
Not deprecated: ✅ Option 3: Directly, with any typing#587 (comment) Made me try const jsonReady = {
foo: "bar",
};
const obj =
await sql`INSERT INTO dodgy_json(dodgy) VALUES (${jsonReady as any}) RETURNING id;`; But has the same issue that some are string values Not deprecated: ✅ |
Option 4: Directly, with any typing and manual casting: const jsonReady = {
foo: "bar",
};
const obj =
await sql`INSERT INTO dodgy_json(dodgy) VALUES (${jsonReady as any}::jsonb) RETURNING id;`;
const check =
await sql`SELECT jsonb_typeof(dodgy) from dodgy_json WHERE id=${obj[0]!.id};`;
expect(check[0]!.jsonb_typeof).toBe("object"); Not deprecated: ✅ |
An aside fact, seems to fail approx 50% of the time in concurrent runs. Eg at the moment running with 10 tests in each of 3 concurrent test files, and consistently getting 14:16, 15:15 failed to passes when running concurrently |
Option 4 and 3 both work against a non-ssl local in docker database. Failing case is SSL against Supabase backend. |
Right, just insert it directly. Do note that simple values won't work as expected - check #392 |
Can you describe the concurrent test? |
Would be nice with a json specific docs section also |
Concurrent test is 3 files identical to this: import postgres from "postgres";
let sql: postgres.Sql;
describe("dodgy sql json 1", () => {
beforeAll(async () => {
sql = postgres(process.env.DATABASE_URL!, { ssl: true });
});
afterAll(async () => {
sql.end();
});
for (let i = 0; i < 20; i++) {
it("tests dodgy json", async () => {
const jsonReady = sql.json({
foo: "bar",
});
const obj =
await sql`INSERT INTO dodgy_json(dodgy) VALUES (${jsonReady}) RETURNING id;`;
const check =
await sql`SELECT jsonb_typeof(dodgy) from dodgy_json WHERE id=${obj[0]!.id};`;
expect(check[0]!.jsonb_typeof).toBe("object");
});
}
}); Being all run with a single jest command. Attempting to get an SSL postgres up to test against. If that succeeds then this may be a supabase issue |
Are you using their load balancer? Could there be a cache inbetween? When it fails is it because the row didn't exist or because the object was a string? |
SSL in docker worked fine, so I think this is a supabase thing.
Yes
Object is a string I'm going to try skipping the loadbalancer |
Yeah, interesting what's going on! Not a nice behaviour 😬! |
I can't connect directly due to ipv6 issues. However, connecting to 5432 which is for session based pooling, everything works as expected. ![]() Default is 6543 which is transaction based. I'll file an issue with the team there. Thanks for the help @porsager |
When run concurrently, this lib seems to insert jsonb data as a string rather than an object.
I've been able to reproduce down to a minimal example.
Steps to reproduce
The text was updated successfully, but these errors were encountered: