2

Original thread on DO (will keep it up to date)

Hello. I am currently developing a mid-to-large project. As i've done before, but using the 1.x branch, I use Features to track all structural and functional components of my site in order to be able to transfer them from my local installation, to the staging server, to the production server etc, while also having svn capabilities and tracking.

The current project consists of 45 Content Types with an average of 15 fields each. There are also ~15 vocabularies, ~10 fieldgroups, and a couple of tons of views.

The problem occurs when trying to track all this stuff with Features. It produces a large (initially, just alpha versions of the Content Types) .info file ( > 100K) which results in the following error:

PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'info' at row 1: UPDATE {system} SET info=:db_update_placeholder_0 WHERE // yada yada yada serialized array of the .info file

Which is totally natural seeing that the collumn is declared as a BLOB.

My question, is how should one go about to manage such a problem?
1) perform a ALTER TABLE system CHANGE info info LONGBLOB /* or MEDIUMBLOB */ NULL DEFAULT NULL? (Ouch)
2) Use branch 1.x instead which is less verbose in the .info file declarations?
3) Break down the project and track it in multiple features? (I'd avoid this cause it will make reverting those features a hellish job since one would depend on the other and vice versa)
4) ...?

I'd appreciate any input on the matter

2 Answers 2

2

The way I see it, you have options:

Features

Break your Features down into smaller Features. Yes, this might make the dependencies a little more effort to manage, but a Feature containing that many content types, as well as other config does seem a little extreme.

If you do break them up, and are worried about dependencies, create a controller module to deal with them. Every time you add/break down a Feature, add it as a dependency to this controller module, then make your new Feature depend on the controller module.

This means that all other dependencies will be inherited by the Feature, but you've only had to declare it in one place. When you then disable any part of your Feature, everything will get disabled - which is the same behaviour as having one monolithic Feature.

As an added bonus, if you perform updates to your Features that require hook_install or hook_update_N, they can go in the controller module.

Configuration Management

If the idea of breaking down your Features really sends shivers down your spine, then check out Configuration Management, which can do what you want (track EVERYTHING), and if pretty easily extensible if you are happy writing your own code. This is also the route Drupal 8 is taking/has taken with configuration management, so with this method you'll be future-proofing your own knowledge.

My personal preference is Features, but if you are looking for something that wouldn't involve you breaking down a huge Feature into smaller ones, then Configuration Management is a solid option.

6
  • Regarding your features break-down approach. My problem is pretty much the order in which i'll have to run the reverts on the new environment, not the dependencies per say. I mean if Feature A contains vocabularies that are used by fields declared in Feature B and C, and you revert B first, you might mess everything up. The "sub" features will need to be constructed in a way that will allow for a specific revert order, right?
    – user5005
    Commented Aug 2, 2013 at 9:08
  • Also, do you reckon option 1 could break anything in the process? Is there any drawback on having the info collumn with increased size?
    – user5005
    Commented Aug 2, 2013 at 9:11
  • It shouldn't matter. If something gets reverted that depends on something else, it should move to "Needs Review" in the Feature UI. Before you get a chance to notice this, the other Features should have also reverted and everything should be fine. I've used this approach before (broken down Feature that has managed to creep up in size), and the reverts were always fine. Any that weren't usually just needed another revert to prod it in the right direction.
    – Chapabu
    Commented Aug 2, 2013 at 9:12
  • I would be super wary changing things in the system table. In fact, changing stuff like that on any contrib/core module table seems dodgy to me. Say the next update to core changes that table in some way...your change will be lost, and your site will break.
    – Chapabu
    Commented Aug 2, 2013 at 9:14
  • Yeah I know the practice, I'd avoid it as well. I am only proposing since it seems like a small change that should not break anything or get reverted with any update. Anyway, thanks for your information, I'll spend the rest of the day testing tracking methods it seems. Configuration Management scares me a bit due to low installations and alpha versions but I'll give it a shot.
    – user5005
    Commented Aug 2, 2013 at 9:29
0

The error happens, because info column is not long enough to serialize data from .info file of the module.

The solution includes:

  • breaking down your Feature module into smaller pieces (e.g. by separating components by type, or by base definition and its instances),
  • increasing size of info column.

If you decide to increase info column, you've the following possibilities:

  • apply simple Drupal core patch from: Increase size of info column in system table (and re-install Drupal),
  • run the following one-time off SQL query:

    ALTER TABLE `system` CHANGE `info` `info` LONGBLOB /* or MEDIUMBLOB */ NULL DEFAULT NULL
    
  • more Drupal way is to change the field by using: db_change_field:

    • as one-time run, either from the code (e.g. as hook_update_X):

      db_change_field("system", "info", "info", array('type' => 'blob', "size" => "big"));
      

      check some field change examples in system_update_7055(),

    • or using drush:

      drush ev 'db_change_field("system", "info", "info", array('type' => 'blob', "size" => "big"));'
      
    • or using appropriate hook (e.g. hook_system_info_alter) which could not work properly for system table,

    • on Drupal install, some example with profile install:

      /**
       * Custom callback to recreate system table.
       *
       * This fixes Drupal issue when data is too long for column 'info'.
       * This happens for large feature modules.
       * @see: https://www.drupal.org/node/2580473
       */
      function myprofile_install_system() {
        try {
          drupal_install_system();
        } catch (PDOException $e) {
          // This catches: SQLSTATE[22001]: Data too long for column 'info'.
          // Then we alter info column in order to resize it.
          db_change_field("system", "info", "info", array('type' => 'blob', "size" => "big"));
        }
        // Rebuild, save, and return data about all currently available modules again.
        system_rebuild_module_data();
      }
      
      myprofile_install_system();
      

      however this could have some side effects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.