graphql-engine icon indicating copy to clipboard operation
graphql-engine copied to clipboard

support adding PG enums as GraphQL enum types

Open maxpain opened this issue 7 years ago • 36 comments
trafficstars

Why Hasura doesn't utilize Postgres ENUM types and doesn't translate them to GraphQL Enums?

maxpain avatar Nov 05 '18 11:11 maxpain

We do not support Postgres ENUM types as of now. Will mark this as a feature request, give a :+1: if you'd like the feature added. :smile:

Till then, you can use single-column tables.

shahidhk avatar Nov 06 '18 12:11 shahidhk

Any updates? It is a very important feature for us.

maxpain avatar Jan 24 '19 07:01 maxpain

We had a discussion about this couple of days. We can go ahead with the implementation with some feedback from the community.

We understand that it is incredibly useful to propagate enums in your database to the GraphQL layer. There are couple of ways in which you typically model enums in the database.

  1. Using Postgres enums: There are certain limitations with Postgres's enums, the most important one is that you can't delete a value from an enum.
  2. The other option is to to use single-column tables for enums as documented here. This some consider is a better practice over using Postgres enum types.

We would like to know which pattern is commonly used so that we can do the appropriate propagation to the graphql layer.

0x777 avatar Jan 24 '19 07:01 0x777

Is there a way to implement a text array, where each value is one of the enumerations. is there a way of doing this without a normalized table?

chunsli avatar Feb 09 '19 10:02 chunsli

+1 for the second pattern @0x777

trekze avatar Feb 09 '19 23:02 trekze

I think it depends on the use case. For values that are likely to change over time, a separate table is better.

But for values that are "set in stone" (the examples that come to mind are static data like country codes, currencies, language codes, measurement units and the likes) a native Postgres enum would be very valuable (and I would argue, also a better practice – more efficient, less error prone).

lordofthelake avatar Feb 17 '19 18:02 lordofthelake

In my opinion, there is a lot of value in equating Postgres enums with GraphQL enums. Neither should change often, and the benefit is great documentation for the API. Using the single-column table pattern in this case would move the error for selecting an invalid value from something that could be checked statically at compile time (with tooling) to something only detected at runtime.

If the value is more flexible or even user defined, I think the single-column table pattern makes sense.

frankdugan3 avatar Mar 07 '19 15:03 frankdugan3

Another issue to consider in supporting this feature is the migration side. As you can see from the below, adding values to an enum type is not possible within "transactional migrations" (or transactions generally)

https://stackoverflow.com/questions/1771543/adding-a-new-value-to-an-existing-enum-type/10404041#10404041

drewwestphal avatar May 27 '19 18:05 drewwestphal

Looks like this might be a blocker for us. We use ENUMs in our existing database and I am getting an error stating that my schema is invalid from the GraphQL CLI.

respectTheCode avatar May 28 '19 20:05 respectTheCode

false alarm. my problem was related to having a row permission with no columns selected. once I fixed that the schema worked.

respectTheCode avatar May 28 '19 20:05 respectTheCode

Hey, this is also a problem with codegen tools, that relies on schema to generate proper enums. Right now possible enum values cannot be detected by such tools as postgres enums are translated to grpahql scalar types.

Krever avatar Jun 12 '19 08:06 Krever

@Krever why you use third party schema generator when we have console app for Hasura :thinking: Any use-case?

mnlbox avatar Jun 12 '19 09:06 mnlbox

@mnlbox I may not have phrased myself clearly enough. Im using codegen tool to generate scala code which will be used as a hasura client. The codegen relies on schema returned by hasura via introspection.

Let me know if you need any more details.

Krever avatar Jun 12 '19 10:06 Krever

any updates on this one?

Fxlr8 avatar Jun 18 '19 10:06 Fxlr8

any updates?

respectTheCode avatar Jul 11 '19 12:07 respectTheCode

@respectTheCode @Fxlr8 Work on this issue has begun. Please expect it to land in one of the next two releases.

dsandip avatar Aug 05 '19 06:08 dsandip

Now I have many redundant tables and relations because of the lack of this feature. @dsandip It's an awesome news that Hasura can handle this for me and I can remove many tables and have a clean data diagram. Thanks guys :wink:

mnlbox avatar Aug 05 '19 06:08 mnlbox

@mnlbox That's great to hear!

Also, clarifying that the plan is to implement enums using single-column tables as outlined by Vamshi here.

dsandip avatar Aug 05 '19 06:08 dsandip

@dsandip what about postgres enums that we already have? For cases when we want to have control over database and only serve it with hasura.

Krever avatar Aug 05 '19 06:08 Krever

@Krever You can continue using Postgres Enums the way you are using them now. The single-column table approach will just create a new table for every enum and associate it with your tables that need this enum's values. You can modify these tables yourself too i.e. you'll have control over them. Does this meet your requirements? If not, could you please elaborate on your use-case.

dsandip avatar Aug 05 '19 07:08 dsandip

Hmm, so it means that if I have a defined enum type and a table using it it will just work? Example:

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
CREATE TABLE person (
    name text,
    current_mood mood
);

And I will be able to work with such table via graphql? Then its alright! Although I dont get the purpose of this new single-column table.

Krever avatar Aug 05 '19 07:08 Krever

@Krever

if I have a defined enum type and a table using it it will just work? And I will be able to work with such table via graphql?

Yes, you can access/modify this table via graphql even now. Here's a sample of an insert mutation:

mutation {
  insert_person(objects: {name: "sandip", current_mood: "ok"}) {
    affected_rows
    returning {
      id
      current_mood
      name
    }
  }
}

Response:

{
  "data": {
    "insert_person": {
      "affected_rows": 1,
      "returning": [
        {
          "id": 1,
          "current_mood": "ok",
          "name": "sandip"
        }
      ]
    }
  }
}

This single-column table will be used to support GraphQL enums (instead of using Postgres enums for this).

dsandip avatar Aug 05 '19 08:08 dsandip

Yes, this I'm aware of. I was hoping that my postgres enums will be expressed as graphql enums in schema.

Krever avatar Aug 05 '19 08:08 Krever

@dsandip some tools like react-admin have some limitation and convention for this single-column table. (For example we force to set this single column name to id or this table not working with react-admin) Also I think maybe it's better to hide this type of table by default in console app. For example user able to show/hide this type of table with an environment variable. Because I have many enum tables and want to keep my console clean. :wink:

mnlbox avatar Aug 05 '19 09:08 mnlbox

Does that PR add support for Postgres ENUMs? The description seems to describe a different feature.

respectTheCode avatar Aug 26 '19 13:08 respectTheCode

Does that PR add support for Postgres ENUMs? The description seems to describe a different feature.

@respectTheCode: From the looks of it, it appears that #2672 does not add support for exposing Postgres enums as Graphql enums. The maintainers may want to consider reopening this issue since the "fix" does not actually accomplish what was requested.

I would love to see another PR that adds support for exposing Postgres enums as GraphQL enums, and leaves the current functionality intact. It would be nice to have the option to use either mechanism. There seem to be some good arguments for both approaches.

kylerjensen avatar Oct 02 '19 20:10 kylerjensen

Note: It looks like Postgres 12 will include support for adding enum values within a transaction. https://www.postgresql.org/docs/12/sql-altertype.html

kylerjensen avatar Oct 02 '19 20:10 kylerjensen

This is a dealbreaker for us as well. We have a lot of enum values sitting around that we really don't want to change into tables for a lot of reasons. Lack of support basically means that we have to instead make endpoints (or alternatively actions) for each field that we want to update (we can read the enum values just fine, but we can't filter by them in where clauses, nor can we run mutations on them). Is there any chance this is getting implemented at some point?

NSilv avatar Mar 01 '21 15:03 NSilv

We moved on and built our graphql backend with Apollo Federation. It turned out to be a lot less work than we had expected and will be a better long term decision too.

respectTheCode avatar Mar 01 '21 17:03 respectTheCode

Happy to see this is reopened again :wink: Really waiting for this feature.

mnlbox avatar Mar 04 '21 08:03 mnlbox