# Schema migration default values for fields

**URL:** <https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178>\
**Category:** GraphQL\
**Tags:** kind:question, kind:enhancement\
**Created:** [October 28, 2020, 11:30am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178 "2020-10-28T11:30:25Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [October 28, 2020, 11:30am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/1 "2020-10-28T11:30:25Z")

</div>

Is it possible to assign default values for new non-nullable fields in case of a schema migration?

Currently all queries will just return a **null** object along with an error message for all objects which don’t have the new field.

---

<div class="post-metadata">

**Author:** ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)\
**Post date:** [October 28, 2020, 11:59am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/2 "2020-10-28T11:59:05Z")

</div>

At the moment, no. There is no concept of default in Dgraph.

As much as it would be nice to have a _default_ directive, it is not the graph way. In a relational model, every row contains data for every column even if the data it contains for that column is nullish. In a graph, only predicates with values exist.

There are two ways to handle this:

1. Set the default value in the application layer. This saves much work from the database and can usually be done in a single line of code.

2. JS hooks (aka lambda functions) are expected in the 20.11 release. With a post query hook, you will be able to provide a default value if the value is null.

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [October 28, 2020, 1:32pm UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/3 "2020-10-28T13:32:21Z")

</div>

Thank you. But 1. and 2. only work if I get all the remaining fields of the requested type, correct?

Currently I just receive:  
[null, null null, {name: “foo”, addedField: “bar” }]

When I for example request all users (with queryUser). I think it would be better to get:  
[{name: “foo1”, addedField: null}, {name: “foo2”, addedField: null}, … {name: “foo”, addedField: “bar”}]

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [November 13, 2020, 7:59am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/4 "2020-11-13T07:59:14Z")

</div>

Hi there, just wanted to bump this thread a bit as I think it deserves more attention.

Let’s assume my application is deployed with a “finished” schema and dgraph is running successfully doing it’s thing.

Now we can push new features in very short timeframes like we could never do before (because dgraph-gql is just awesome). New features will ultimately almost always bring new data to the database.

Now of course I could set the default values in the application layer. This however is error prone and in every new \*.tsx I write I have to remember for which fields of which types I have to define default values. This can get out of hands very quickly.

Secondly, assume this schema:

```auto
type UserPermissions {
   ... 
   canUseFeatures: [String!]! # new field
}

```

So, I added the field `canUseFeatures` to my type which is required (!). When I migrate this schema to my existing database, currently all existing nodes will have **null** on that field. Querying those nodes will result in `error: canUseFeatures has to be specified!` (or something along these lines). The graphql schema validation fails.

Therefore, I once again propose to add a @default directive that is either used to:

1. Set the corresponding field when the client is not specifying a value in the `addType` mutation
2. Set the corresponding field to the default value for all existing nodes of the type in question.

---

<div class="post-metadata">

**Author:** ![pawan](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/pawan/32/1946_2.png) [@pawan](https://discuss.dgraph.io/u/pawan)\
**Post date:** [November 13, 2020, 8:49am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/5 "2020-11-13T08:49:55Z")

</div>

> [@maaft](#):
>
> Set the corresponding field when the client is not specifying a value in the `addType` mutation

This is something that we can introduce and it will work with newly added data via GraphQL mutations.

> [@maaft](#):
>
> Set the corresponding field to the default value for all existing nodes of the type in question.

This sounds like a data migration that is best handled by the app developer in my opinion for various reasons. As an app developer, you have the most flexibility and knowledge of what to set this value to and can do at a time that is most suitable for your app.

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [November 13, 2020, 9:01am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/6 "2020-11-13T09:01:31Z")

</div>

> [@pawan](#):
>
> This sounds like a data migration that is best handled by the app developer in my opinion for various reasons. As an app developer, you have the most flexibility and knowledge of what to set this value to and can do at a time that is most suitable for your app.

Well, it’s only a complex migration task if the new field derives it’s value from other existing data and differs from node to node. If that is the case, the migration has to be done of course externally.

However, a lot of times it would be just new added primitive fields (String, Int, Float, Boolean, maybe lists of primitives) that **don’t** depend on existing data and it should be easy (and useful) to provide default values for them I think. We could save so much time (both downtime and development-time) when these default values would just be inserted on a schema upgrade.

As an alternative to migrating the db and inserting new fields with default data, the @default directive could also work when the type is being queried. If a field is **null** , the default value is returned instead. I think that this approach is even preferable because it takes less time to implement and doesn’t need to iterate over and change the db. This could be implemented similar to @cascade.

---

<div class="post-metadata">

**Author:** ![pawan](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/pawan/32/1946_2.png) [@pawan](https://discuss.dgraph.io/u/pawan)\
**Post date:** [November 13, 2020, 9:12am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/7 "2020-11-13T09:12:04Z")

</div>

> [@maaft](#):
>
> As an alternative to migrating the db and inserting new fields with default data, the @default directive could also work when the type is being queried. If a field is **null** , the default value is returned instead.

Yes, I was thinking about that as well. This is a possibility that we could look into as it doesn’t require rewriting data in the DB for nodes.

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [November 13, 2020, 9:30am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/8 "2020-11-13T09:30:17Z")

</div>

So we would have three options here going forward:

**Option A:**

```auto
directive @default(value: AllowedTypes!) on FIELD_DEFINITION

type Foo {
   bar: String! @default(value: "helloworld")
}

```

Generated mutation:

```auto
type Mutation {
   addFoo(bar: String): Foo #note that bar is optional
}

```

If no `bar` is specified when adding new nodes (or for existing nodes that didn’t have this field), the query:

```auto
query {
   queryFoo {
      bar
   }
}

```

will return:

```auto
{ 
   QueryFoo: [
      {
         bar: "helloworld"
      },
      {
         bar: "helloworld"
      }
   ]
}

```

**Option B:**

```auto
directive @default(value: AllowedTypes!) on FIELD
type Foo {
   bar: String!
}

```

Query:

```auto
query {
   queryFoo {
      bar @default(value: "lol")
   }
}

```

This would allow for more flexibility (i.e. different default values in different environments).

**Option C** :  
Both! Combine the ease of mind of Option A with the flexibility of Option B. We just have to figure out good names for the directives then.

Opinions?

@pawan did you have time to discuss this internally?

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [February 22, 2021, 6:31pm UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/9 "2021-02-22T18:31:15Z")

</div>

Is there any progress on this? I would use this feature heavily.

---

<div class="post-metadata">

**Author:** ![maaft](https://avatars.discourse-cdn.com/v4/letter/m/4af34b/32.png) [@maaft](https://discuss.dgraph.io/u/maaft)\
**Post date:** [May 11, 2021, 11:50am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/10 "2021-05-11T11:50:58Z")

</div>

@pawan

Hi again,

is there any progress on this?

In my opinion this is a **key-feature** for a database. When you add new fields, the first thing you want to do is to migrate your old data. Or am I overlooking some existing mechanism for this?

---

<div class="post-metadata">

**Author:** ![eugaia](https://avatars.discourse-cdn.com/v4/letter/e/f0a364/32.png) [@eugaia](https://discuss.dgraph.io/u/eugaia)\
**Post date:** [May 11, 2021, 11:07pm UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/11 "2021-05-11T23:07:54Z")

</div>

@hardik - If this idea of having @default isn’t in the roadmap yet, I second adding it.

---

<div class="post-metadata">

**Author:** ![BenW](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/benw/32/7532_2.png) [@BenW](https://discuss.dgraph.io/u/BenW)\
**Post date:** [July 9, 2021, 6:18am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/12 "2021-07-09T06:18:02Z")

</div>

Just adding my vote for this. Not being able to set a default value for `Boolean!` creates a [three state problem](https://thoughtbot.com/blog/avoid-the-threestate-boolean-problem#:~:text=Yep%20%2D%20it%20can%20be%20null,true%20%2C%20false%20%2C%20or%20NULL%20.)

---

<div class="post-metadata">

**Author:** ![Paul](https://avatars.discourse-cdn.com/v4/letter/p/bbe5ce/32.png) [@Paul](https://discuss.dgraph.io/u/Paul)\
**Post date:** [January 1, 2022, 11:17am UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/13 "2022-01-01T11:17:52Z")

</div>

Creating a new schema and coming over from Prisma and mysql.

Would definitely love to see a @default as promised by @maaft

---

<div class="post-metadata">

**Author:** ![amaster507](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/amaster507/32/4123_2.png) [@amaster507](https://discuss.dgraph.io/u/amaster507)\
**Post date:** [January 1, 2022, 3:50pm UTC](https://discuss.dgraph.io/t/schema-migration-default-values-for-fields/11178/14 "2022-01-01T15:50:14Z")

</div>

It was added in 21.12 not yet released to Dgraph Cloud
