Field type modules cannot maintain their field schema (field type schema change C(R)UD is needed)

Created on 10 October 2010, about 14 years ago
Updated 30 August 2024, 3 months ago

Coming from #934050: Change format into string :

Relatively complex problem space; the below list of problems are depending on each other, so it does not make sense to split them into separate issues. The resolution needs to take all of them into account.

Problem

  • A field schema is set in stone after initial creation and cannot be updated.

Goal

  • Field type modules have to be able to programmatically update their field schema.

Required functionality
For field schema:

  • Add new column (e.g. new setting)
  • Change column settings (e.g. different size)
  • Remove column (e.g. removed setting)
  • Rename column (e.g. a field name was too long, had a typo or needs rename for other reasons)

For field(s):

Details

  • As with any other module, the field schema of field type modules will change over time. Currently, Field API tries to prevent any schema updates on the assumption that the schema update has been triggered via Field UI. While limiting the possibilities of the user interface makes sense to some extent, there must be a way for field type modules to perform intended, safe, and wanted field schema updates, just like any other module has to be able to update its schema. Field type modules are no exception to that rule.

    AFAICS, Field UI already implements the necessary logic to prevent users from updating a field schema through the UI. The current patch does not change the runtime API of field_update_field(), so it still disallows field schema changes. Instead, an update helper function is introduced, which basically is the same as field_update_field(), but works within the update.php environment and does not disallow schema changes.

EDIT: Splitted the other issues with field_update_field() into #937554: Field storage config entities 'indexes' key

Helper / workaround

https://www.drupal.org/project/devel_schema_change_helper was created as a helper module for this, until this is solved in core

Feature request
Status

Needs work

Version

11.0 🔥

Component
Field 

Last updated about 10 hours ago

Created by

🇩🇪Germany sun Karlsruhe

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States amaria

    I am still having a problem with this. After updating my field schema with a new column, and use code from #60/#66 in an update hook, it doesn't work.

    When I get the columns from the table mapping...
    $columns = $table_mapping->getColumnNames($field_name);
    It does not contain the new property yet so it fails at this...
    $field_exists = $schema->fieldExists($table_name, $columns[$property]);

    Am I missing something before I run this code?

  • 🇩🇪Germany Anybody Porta Westfalica

    Once again ran into this, now in 🐛 SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'field_access_role_id' cannot be null Fixed . I'll ask @Grevil if he can help to push things forward here #74 + #79.

    Could we get some core maintainer feedback on #80 and the implementation in general perhaps?
    To ensure this goes into the right direction and is best practice? We shouldn't waste time, this is really essential to maintain field schema changes in contrib.

  • 🇺🇸United States apmsooner

    Same as #88 for me. The code examples the patch work is based on don't work exactly right for me. Tested with drupal 10 php 8.1.

    1. For adding new column, I think this $field_exists = $schema->fieldExists($table_name, $columns[$property]);
      .... should be this: $field_exists = $schema->fieldExists($table_name, $property);
      Otherwise it fails with php error...
    2. This $manager->updateFieldStorageDefinition($field_storage_definition); wipes out tables with existing data so I scrapped it and did my own thing. Through trial an error I got something working in a branch of a very complex module scenario. I don't claim it to be perfect but its working. The key part i needed was restoring the existing data after modification which isn't documented well anywhere. https://git.drupalcode.org/project/custom_field/-/blob/updater_service/s...

    Open to thoughts and suggestions on my approach. It is indeed more complex than I anticipated.

  • 🇩🇪Germany Anybody Porta Westfalica
  • 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10

    Hiding patches

    Should we change this into a meta and split it into three separate issues in order of difficulty:

    1. Adding a new column with a default value (static value)
    2. Removing a column
    3. Updating a column

    Both custom field and composite field have a concrete use case for this, particularly 1 and 2.

  • 🇩🇪Germany Anybody Porta Westfalica

    @larowlan: I'm unsure, because the functionality might be quite similar and I'm not sure, that would speed things up?
    You decide! :)

    We've created https://www.drupal.org/project/devel_schema_change_helper some weeks ago because we needed those helpers again and again. We could also prepare the functionality there and move it over into core once it's finished to have a working solution in contrib. What do you think?

    I added the link to the issue summary!

    Happy to see progress here, this is really really important for DX!

Production build 0.71.5 2024