-
-
Notifications
You must be signed in to change notification settings - Fork 688
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
[Pg] Fix jsonb field escaping data before insert #666
Conversation
fix issue with escaping data on jsonb pg
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integration tests fail with this change.
I have fixed postgresjs test, now should I extend insertjson with a proper jsonb query like
Or better to leave just the jsonb query?
This test will fail on by branch for pg driver Is there a way to do mapToDriver by driver? |
sure, go ahead @LeonAlvarez |
great! jsonb support is a must <3 |
For now I'm solving it on user land as there is no simple way to change behaviour of type for each driver on core. If you are using postgresjs and jsonb simply create a custom jsonb type and use it isntead of the one from pg-core import { customType } from 'drizzle-orm/pg-core';
const jsonb = customType<{ data: any }>({
dataType() {
return 'jsonb';
},
toDriver(val) {
return val as any;
},
fromDriver(value) {
if (typeof value === 'string') {
try {
return JSON.parse(value) as any;
} catch {}
}
return value as any;
},
});
export default jsonb; |
Using your workaround @LeonAlvarez , its working great. |
This is what I'm using based on @LeonAlvarez's solution with TS types and based on Drizzle's own example: https://orm.drizzle.team/docs/custom-types (except driverData should be TData not string for it to work) I assume it will work with 'jsonb' too. export const customJson = <TData,>(name: string) =>
customType<{ data: TData; driverData: TData }>({
dataType() {
return 'json'
},
toDriver(val: TData): TData {
return val
},
fromDriver(value): TData {
if (typeof value === 'string') {
try {
return JSON.parse(value) as TData
} catch {}
}
return value as TData
},
})(name) |
Any updates? 🥇 |
Has anyone managed to use the customType or an alternative approach to insert when the column type is jsonb[] ? The customType approach worked for jsonb, but I'm stuck on jsonb[]... create table test ( export const test = pgTable("test", { await db.insert(test).values({ I can write/read data fine. But getting below on list... Query: insert into "test" ("id", "data", "list") values (default, $1, $2, $3) -- params: [{"name":"Ali","age":34}, "{[object Object],[object Object]}"] |
I don't know if there is a better way but this works fine for me export const customJsonb = <TData>(name: string) =>
customType<{ data: TData; driverData: TData }>({
dataType() {
return 'jsonb'
},
toDriver(val: TData) {
return sql`(((${JSON.stringify(val)})::jsonb)#>> '{}')::jsonb`
},
fromDriver(value): TData {
return value as TData
},
})(name) and this can convert all the stringifyed JSON UPDATE table_name
SET column1 = (column1#>> '{}')::jsonb,
column2 = (column2#>> '{}')::jsonb
; |
I was going to work on this issue but I noticed this PR. What's the status @LeonAlvarez ? Let me know if you can complete the fix or if you'll prefer me to take over. |
Closing this in favor of #1641 |
RN Jsonb column is incorrectly escaping data before inserting it which end up in
"{\"external_id\":40}"
instead of{"external_id": 40}
. Because of that queries using jsonb syntax are not working for example the following query:on current drizzle status we are forced to first cast column to jsonb as escaped data is just a string (which can be stored on json be but it really isnt jsonb)