Feature request: Directive that indicates that @id fields should be auto-populated on creation

I have two questions:

  • Why is the @id field needed for upserts, what prevents Dgraph from just checking against it’s native uid?
  • Is there any reason why an @id field shouldn’t be/can’t be auto-populated by Dgraph?

On the second point, it’d be great if there was a directive that indicated that an @id field should be auto-populated by Dgraph with a random ID when the node is created. Just seems like the kind of work the database should be doing…?

I think a main use case for it is for uids from other DB’s for syncing purposes, or maybe usernames or something, so those wouldn’t be auto-create scenarios.

But I like the idea.

But it seems like you’d only want to use it if you weren’t satisfied with the native of format and you wanted a different format like integer or uuid for example, no? So which should that be?

You might be able to accomplish it with a @lambda mutation? Not sure there is a onCreate one though.

1 Like

Yeah, there are a lot of variables here. What and how is so broad that it would be hard to make something that works for a variety of use cases without some kind of onCreate

I am assuming this should be under graphql?

Because if you know the id field, it would be an update, not an add - upsert. There is no getPost by @id, and there is no addPost-upsert by ID.

This also has to do with the fact that you can add multiple fields at once, but you can only edit one field at a time. The backend code would have to differentiate between what is a new Post, and what is an update Post. Is there a unique ID or @id? etc…

While this makes sense, I agree that it would be much easier to have one update function that allows you to create, or modify nodes and would automatically match the existing nodes that have an @id or an ID field input.

A lot of the problems Dgraph has not yet solved have already been solved by SQL databases. In this case, we should add an AUTO_INCREMENT @directive.

Something like:

Type {
  uid: ID!
  id: Int! @auto_increment(start: 565)
  ...
}

If you needed to change the start value, just change it in the schema.

Just a thought.

J


Update: So the start would not work here as every time you update the schema, you would have to think about the start number. However, there could be an internal variable you could set somewhere in dgraph, a globals section maybe, that stores that number to change it.

1 Like

well in a way it would work if the process was smart about it like MySQL handles it. In the schema in MySQL for an AI field you can define a start. But if you define a start that is below the some existing data then the incrementing value stored in the database actually gets set to the minimum value of the data. So while it would take a bit more logic, it still would be possible to have it in the schema and is where I would expect it to be defined. That would also make it easy to say, ok let’s skip the next X and start from here on out at Y with a schema deploy. So the value in the schema would not be the actual next value, but instead it would be the minimum value to use as next and the minimum of the actual data +1 would be next.

For an even more advanced mode, it is possible in MySQL databases to do a strange logic to count evens, or odds, and I think even more advanced options. At one time I had two MySQL databases on separate servers that a user could write to either one and read from either one and they would sync whenever they were capable of doing so. Sort of like an offline database capability. But that is another entire discussion :wink:

1 Like

Just a thought, can’t Dgraph’s Zero be used to manage and issue the numeric ID similar to the UID? The use case is to preserve the IDs even after a database migration since the UID can change.

2 Likes

theres currently an open PR that introduces the @default directive: https://github.com/dgraph-io/dgraph/pull/8017

This should be extended for every kind of field IMHO.

E.g. for type String this could be:

type Foo {
    cuid: String! @id @default("cuid")
    uuid: String! @id @default("uuid")
}

This would mark cuid and uuid as optional arguments to addFoo. So you could still override the default, otherwise the specified value/function will be used.

If you like this, make some noise on the PR everybody or contribute yourself!

2 Likes