is it possible to do an “upsert” when loading comp...
# prisma-whats-new
s
is it possible to do an “upsert” when loading complex data? for instance: mutation { createThing( name: "Thing Name", samples: [ { dataPoints: [ { value: 99, dataPointType: { name: "MY_TYPE" } } ] } ] ){ id, name, samples { dataPoints, { value, dataPointType { name } } } } } if i want the dataPointType.name field to be unique, can a new node only be created if it doesn’t already exist? i don’t want the dataPointType to be an enum because i want to hang more fields off of it.
n
@stlbucket if you set the name field to unique I believe what happens is that the thing will be created but the samples and data thing won't be created and you receive an error. Right now an upsert here is not possible, but you could try to create the data point first, if it does not exist yet create it and take its id and pass it to dataPointsIds in your mutation instead
s
aye. was just hoping there was a fancy way to do it in one shot
n
We are looking to make situations like that simpler. Did you have an exact approach/syntax in mind for that?
s
no but i could try and come up with something
seems like updateOrCreateDataPoint could be involved? i notice @alex_ye is asking a question on the main thread about that? i’m not sure how that works either, but something like: updateOrCreateDataPointType( name: "DataPointType-b776d13f-c0d6-4436-84ac-69c35346df16", description: "my new description if it already exists" ) { id, name, description }
but updateOrCreate doesn’t seem to be for that - i’ve not looked at it before
but a method that only works if all unique fields are present of some sort would seem necessary? but that is probably breaking all kinds of rules
n
yea updateOrCreate is one possible approach (also see my answer in the other thread), but in your case you want to apply some kind of upsert logic in the nested mutation, so that's yet another thing
s
yep - how do the guts of the nested mutation work? i would imagine that you would need to do it there. and maybe some kind of flag at the entity level to indicate whether you wanted that behavior or to just reject the query?
slightly different concern: the way nested mutations can partially succeed, but then fail halfway through is actually kinda bad, imo.
that starts to get into transaction territory, yeah?
n
and maybe some kind of flag at the entity level to indicate whether you wanted that behavior or to just reject the query?
yea something like that seems reasonable
let me actually check how it works as I'm currently not sure
s
something like update or create would seem to do it if it could work off unique field(s) by default other than ‘id’. if you could do something like: … samples: [ { dataPoints: [ { value: 99, dataPointType: updateOrCreateDataPointType( name: "MY_TYPE" ) { id, name } } ]
but i bet nesting the mutation call like that would not work
but then you wouldn’t need an external flag - your mutation would be explicit in it’s intention
n
right that makes a lot of sense. we are thinking about different ways to accomplish the selection of nodes other than the id for update mutations. expanding that concept to nested mutation is a great idea, thanks!
s
are nested mutations doable?
n
I guess so! We certainly have to research this more in details but we have some ideas here
s
looking at the other thread, i’m not seeing the full value in specifying update and create sections for updateOrCreate… to me, it seems it should really be working on a combination of all unique fields except id. if they exist, you update. if they don’t, you create. if you already know the id for the update section, then why not just update explicitly? i think these two threads could be related, but putting this here so as not to clutter the other.
n
yea let's have that discussion here.
Yep we're working on that change already. We got similar feedback before 🙂 there are use cases that are handled by the current
updateOrCreate
, but bringing unique fields into the equation adds a lot more flexibility
s
pretty sure if it worked like that AND if you could nest mutations, it would solve this issue. the bigger context here is for bulk data loading, btw - though no doubt useful in other areas.
n
Indeed!
Alright, just confirmed the behaviour, if nested mutations fail the containing mutation is still executed - you're arguing that this should not be the case, while we've seen other use cases where this is the expected behaviour
s
oh i think that’s probably a bigger issue. but it is a little ambiguous when some of it fails and some doesn’t. the cases i’ve run into all are around loading a bunch of data where the inner mutations are things like lookup types, etc. if you start pulling that thread, i would think you would want to look at having some sort of transaction context where the whole thing would be rolled back - but that gets into how you implement the underlying db interaction, which is opaque to me on graph.cool (and i want it to be :)). what i would really want from this thread is: - nested updateOrCreate - have updateOrCreate work off all unique fields EXCEPT id - if that behavior conflicts with how updateOrCreate is currently intended to work, maybe name it something else like ‘upsert’ (tho that might be wrong as well)
that would make the inner fail/outer succeed a non-issue in my bulk-load scenario
… not to make it more complex, but this could apply to enums as well. in my specific case, i want a more complex type so i can hang more data off it. but often i would just want an enum. but pretty quickly i would see a need to add enum values on the fly as well. that probably gets into the upcoming enum functionality tho, and could be a fundamentally wrong way of looking at enums...