steebchen / prisma-client-go

Prisma Client Go is an auto-generated and fully type-safe database client
https://goprisma.org
Apache License 2.0
2.09k stars 94 forks source link

Select only requested fields #346

Closed araufdogan closed 4 months ago

araufdogan commented 3 years ago

Hello,

I'm trying to build a GraphQL service using gqlgen and prisma2. I want to select only requested fields from prisma using gqlgen field collection, is it possible? Does prisma golang client supports field selection?

steebchen commented 3 years ago

Unfortunately, it's not supported yet. We want to have the feature at some point but don't have the capacity for it in the near future.

steebchen commented 3 years ago

Syntax proposal:

users, err := client.User.FindMany().Select("id", "email", "username").Exec(ctx)

With gqlgen:

func (r *Resolver) Users(ctx context.Context) ([]db.UserModel, error) {
    fields := graphql.CollectAllFields(ctx)
    return users, err := client.User.FindMany().Select(fields...).Exec(ctx)
}

The users variable would still be of type []db.UserModel, but the connection would only fetch the selected fields, and unselected fields would be nil or the Go default value.

jonrainier commented 2 years ago

Any updates / community accepted way to do this?

steebchen commented 2 years ago

No, and we don't expect to have this feature anytime soon due to constrained resources

fragdance1 commented 2 years ago

Don't know if this still is requested, but just got to playing around with prisma go (after prisma ts), and got it to work somehow:

    var folder db.MediaFolderModel
    query := global.DB.MediaFolder.FindUnique(db.MediaFolder.Name.Equals("cache")).ExtractQuery()

    query.Outputs = []builder.Output{{Name: "id"}, {Name: "name"}}
    err := query.Exec(context.Background(), &folder)

Returns the following:

{```

"id": 5,
"name": "cache",
"path": "",
"type": ""

}



i.e. path and type is not fetched (actually not in json from prisma engine), but set as empty strings because of golang struct
steebchen commented 2 years ago

Oh wow, that is pretty cool @fragdance1. If you want to create a PR to add a method .Select([]string{}) to the query builder to select these fields, I'd be happy to review and merge it!

I think the question left for this issue specifically would be if passing the args directly from gqlgen would work.

fragdance1 commented 2 years ago

Actually forked it to https://github.com/fragdance1/prisma-client-go in order to implement just that (and not mess anything up), and now I can call it like:

episodes, err := global.DB.Episode.FindMany(db.Episode.ShowID.Equals(id)). Select([]string{"name", "id", "episodeNumber", "seasonNumber", "progress", "owned"}). With(db.Episode.VideoFiles.Fetch(). Select([]string{"id", "extension"}). With(db.VideoFile.Subtitles.Fetch())). Exec(context.Background())

I've also added a replacement function ExecJson that returns the raw json from the call, thus excluding the fields not retrieved. Feel free to check it out/grab the code

steebchen commented 2 years ago

@fragdance1 I think this would be awesome to have in the client. I'd be happy to review and merge a PR for this!

Regarding implementation, I think it's fine if the missing fields just use their respective Go default values, beacuse there's not much to do about it anyway.

fragdance1 commented 2 years ago

@steebchen Just tried to push to a new branch feat/prisma-select-statement, but got access denied.

Anyways, the code in my branch turns this: bild

to this: bild

When using the code: bild

As can be seen in the screenshots it works on multiple levels (here the credit goes to you), and I have select on both the Episode model and the relational Videofile model

steebchen commented 2 years ago

@fragdance1 You can just push it to your repo and then create a PR from your branch to this repo

blyxyas commented 2 years ago

@fragdance1 May you create a PR with your change, please?

fragdance1 commented 2 years ago

Hi,

sorry about the delay, got sidetracked at work.

Problem is that I pushed a lot of changes, so no single 'Select'-branch. Think the easiest is for you to make the changes (there aren't that many).

In generator/templates/actions/find.gotpl add

func (r {{ $result }}) Select(params []string) {{ $result }} { r.query.Outputs = []builder.Output{} for _, q := range params { r.query.Outputs = append(r.query.Outputs,builder.Output{ Name: q, }) } return r }

And that's it

On Tue, Aug 16, 2022 at 5:25 PM Alex @.***> wrote:

@fragdance1 https://github.com/fragdance1 May you create a PR with your change, please?

— Reply to this email directly, view it on GitHub https://github.com/prisma/prisma-client-go/issues/346#issuecomment-1216791712, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFZKQZXEVDUCTNXCQP7KL2DVZOXH3ANCNFSM4VHCLP5Q . You are receiving this because you were mentioned.Message ID: @.***>