supabase / postgrest-js

Isomorphic JavaScript client for PostgREST.
https://supabase.com
MIT License
1.07k stars 141 forks source link

Camel case to snake case name conversion #204

Open joshiain opened 3 years ago

joshiain commented 3 years ago

Feature request

Is your feature request related to a problem? Please describe.

postgres column naming conventions suggest using snake_case. Javascript variable naming conventions typically use camelCase. This leads to a few issues when trying to interact with the postgres database using the postgrest-js api.

I either have to use snake_case for my object keys in my javascript code, but this is then inconsistent with the rest of my code.

I could also use camelCase for my postgres column names, but then this creates a lot of friction with queries as casing is ignored without "".

Or I could automatically convert the keys from camelCase to snake_case before sending any data, and from snake_case to camelCase when receiving data.

Describe the solution you'd like

A config setting, or option that will automatically convert object keys from camelCase to snake_case when sending data.

Having a table with columns: user_name and date_added. The following would work:

const data = [{userName: "abc123", dateAdded: "2021-01-01"}]
await postgrest.select('table').insert(data)

And similarly when querying for data, the returned object would have the column names converted from snake_case to camelCase.

Describe alternatives you've considered

pg-promise, knex.js, and objection.js provide similar utils to help with this issue.

Additional context

Add any other context or screenshots about the feature request here.

wiesson commented 2 years ago

This would be soooo helpful :)

steve-chavez commented 2 years ago

Renaming columns on reads is possible, but not on writes(https://github.com/PostgREST/postgrest/issues/1773) - once the latter is solved postgrest-js could autogenerate aliases to solve this.

wiesson commented 2 years ago

I ended up with converting my db to the camel case format and accepted that I have to live with quotes forever

steve-chavez commented 2 years ago

Another option for this: https://github.com/supabase/supabase/discussions/7136

irohitb commented 1 year ago

If this helps anyone, I have been using ts-case-convert and it works like magic.

devhandler commented 1 year ago

it would be so much easier if postgres can simply ignore casing without quotes, treating select camelcasecol from tbl the same as select camelCaseCol from tbl. then everything is solved.

not sure why do they still throw errors when you reference camelCase col in all lower case letters. the reverse actually works. you can reference lower case letters of column names by using uppercase letters

weeksie commented 1 year ago

This is extremely frustrating. It's a very simple move to add a conversion. Knex does it without sweating. The "accepted" option is basically to break encapsulation so that you can tell you have a data object b/c its properties are in snake case. I appreciate "opinionated" frameworks as much as the next guy but a typescript/javascript framework (of all things) should have this affordance.

wiesson commented 1 year ago

Offtopic: I'm also hoping that at some point, it will be added to postgrest. It feels like a feature were I would apply for a job, fix that one thing and leave 🙈

alvgaona commented 10 months ago

+1

isaachinman commented 10 months ago

Can anyone here elaborate as to how you are using ts-case-convert to automatically wrap methods?

joryphillips commented 8 months ago

@isaachinman you probably figured this out a while ago, but this is more or less it. You'd want to do the reverse for write operations.

import { objectToCamel } from "ts-case-convert";

export async function getThingById(id: string) {
  const tableQuery = supabase
    .from("my_cool_table")
    .select("*")
    .eq("id", id);

  const { data, error } = await tableQuery;
  if (error) throw error;

  return objectToCamel(data);
}
veloware commented 2 months ago

If this helps anyone, I have been using ts-case-convert and it works like magic.

Ive gave this a go, and it works, but I'm curious if you ran into any complexities regarding inferring the TS types? as in -

normally you could do -

const myQuery = supabase.from("xxx")...

type MyQueryResponse = QueryData<typeof myQuery>;

and then MyQueryResponse would have all of the snake_case properties, but im curious if you know how to infer types after the objectToCamel conversion has happened?

EDIT

I've quickly found the answer, in ts-case-convert there is a already types for that, e.g. -

type MyQueryResponse = ObjectToCamel<QueryData<typeof myQuery>>;

MyQueryResponse now has camelCase property names