<p>No, don't delete fields in a migration. Project config changes should always happen through the <code>config/</code> folder, never through a migration, so you have a <a href="https://craftcms.com/events/sessions/the-unreasonable-efficiency-of-craft-and-git" rel="nofollow noreferrer">single source of truth</a>.</p>
<p>Deleting a field and migrating its content in one go is <em>possible</em>. Deleting a field will not immediately delete the fields content in all elements, it will stick around in the JSON blob in the <code>content</code> column until the next time an entry is saved. What you can do is write a migration that will go through all the JSON blobs and replace the old field's UID with the new field's UID. In fact, that's how the <a href="https://craftcms.com/docs/5.x/upgrade.html#field-and-entry-type-consolidation" rel="nofollow noreferrer"><code>fields/merge</code> command</a> does it. However, that requires you to understand all the details of how content is stored in the database and write a fiddly migration, I usually avoid that.</p>
<p>To replace one field with another and migrate existing contents, I usually take the following approach:</p>
<ol>
<li>Rename the old field to something like <code>myfield__OLD</code>. In all field layouts where the field is used, add a user condition that limits the field to be only visible to admins.</li>
<li>Create the new field to replace the old one, and add it to all field layouts where it's used, next to the old field.</li>
<li>Write a migration that moves the content from the old field to the new one, which is trivial since both fields exist in the field layout simultaneously.</li>
<li>Make any necessary changes to your templates and modules.</li>
<li>Deploy those changes to production. Now the content will be migrated and all templates and other code will use the new field. The old field still exists, but is no longer visible to regular authors.</li>
<li>After that, delete the field everywhere it's used. Finally, delete the old field. Then deploy to production again.</li>
</ol>
<p>By separating those changes into two deployments, you don't have to find awkward workarounds for the old field being gone before the new one takes its place.</p>

CC BY-SA 4.0
2024-11-11T18:46:42.810Z
@ MoritzLost That's an awesome and very complete answer! Thanks a lot!

While reading, I realized that I've probably hit the edge case of that scenario:
The field I'm tried to migrate from is the title of an entryType…
The whole background it that we want to make that field optional.

Instead of deleting it, we wanted to hide it. But hiding, from my tests, deletes the data in those fields. 

So to adapt your approach I would need to do this differently:

1. leave the title field visible (with the downside of having two fields)
6. hide the field
lejoe
CC BY-SA 4.0
2024-11-12T16:13:51.593Z
@lejoe You're right, if your migrating data from the title field, you need to hide it instead of deleting it. You can turn off the option **Show the title field** in the entry type. Then either leave the **Title Format** empty or just set it to output your new field. You _might_ have to do that in two separate steps – not sure if the title will be updated before you have a chance to migrate the content, you'll need to test that in your dev environment.
MoritzLost
CC BY-SA 4.0
2024-11-18T17:17:20.653Z
Cheers for the fast, precise and helpful answers!
lejoe
CC BY-SA 4.0
2024-11-09T08:54:43.023Z
2024-11-09T08:54:43.023Z
MoritzLost
<p>I want to replace field X from an entryType by another field Y and migrate the content.</p>
<p>I did it that way:</p>
<ul>
<li>add field Y in the config (saved to git)</li>
<li>wrote a migration script for all entryType instances to copy the content of field A to field B</li>
</ul>
<p>No this how do I get about deleting the field X from the entrytype?</p>
<p>Should I do that in the migration? → if yes, won't it conflict with the config in git?</p>

<migration><entry-type><craft5>
Deleting old field after migration
# Deleting old field after migration

(Asked by: username_0 on 2024-11-08)

I want to replace field X from an entryType by another field Y and migrate the content.

I did it that way:

* add field Y in the config (saved to git)
* wrote a migration script for all entryType instances to copy the content of field A to field B

No this how do I get about deleting the field X from the entrytype?

Should I do that in the migration? → if yes, won't it conflict with the config in git?

**Tags:** migration, entry-type, craft5


---

## 1 answers

### Answer by username_1 on 2024-11-09. Score: 0 | Accepted answer

No, don't delete fields in a migration. Project config changes should always happen through the `config/` folder, never through a migration, so you have a [single source of truth](https://craftcms.com/events/sessions/the-unreasonable-efficiency-of-craft-and-git).

Deleting a field and migrating its content in one go is *possible*. Deleting a field will not immediately delete the fields content in all elements, it will stick around in the JSON blob in the `content` column until the next time an entry is saved. What you can do is write a migration that will go through all the JSON blobs and replace the old field's UID with the new field's UID. In fact, that's how the [`fields/merge` command](https://craftcms.com/docs/5.x/upgrade.html#field-and-entry-type-consolidation) does it. However, that requires you to understand all the details of how content is stored in the database and write a fiddly migration, I usually avoid that.

To replace one field with another and migrate existing contents, I usually take the following approach:

1. Rename the old field to something like `myfield__OLD`. In all field layouts where the field is used, add a user condition that limits the field to be only visible to admins.
2. Create the new field to replace the old one, and add it to all field layouts where it's used, next to the old field.
3. Write a migration that moves the content from the old field to the new one, which is trivial since both fields exist in the field layout simultaneously.
4. Make any necessary changes to your templates and modules.
5. Deploy those changes to production. Now the content will be migrated and all templates and other code will use the new field. The old field still exists, but is no longer visible to regular authors.
6. After that, delete the field everywhere it's used. Finally, delete the old field. Then deploy to production again.

By separating those changes into two deployments, you don't have to find awkward workarounds for the old field being gone before the new one takes its place.

> **Comments:**
> **username_0**: @ username_1 That's an awesome and very complete answer! Thanks a lot!  While reading, I realized that I've probably hit the edge case of that scenario: The field I'm tried to migrate from is the title of an entryType… The whole background it that we want to make that field optional.  Instead of deleting it, we wanted to hide it. But hiding, from my tests, deletes the data in those fields.   So to adapt your approach I would need to do this differently:  1. leave the title field visible (with the downside of having two fields) 6. hide the field  
> **username_1**: @username_0 You're right, if your migrating data from the title field, you need to hide it instead of deleting it. You can turn off the option **Show the title field** in the entry type. Then either leave the **Title Format** empty or just set it to output your new field. You _might_ have to do that in two separate steps – not sure if the title will be updated before you have a chance to migrate the content, you'll need to test that in your dev environment.  
> **username_0**: Cheers for the fast, precise and helpful answers!  

---

