Hi,

I am updating a D7 website into B and I am getting to #1015 in the update.php script when it throws a PDOException (see watchdog table entry below):

| 2024-03-12 09:11:58 | menu | a:6:{s:5:"%type";s:12:"PDOException";s:8:"!message";s:2065:"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'langcode' in 'field list': UPDATE {menu_links}...

I have checked the backdrop dB and these are the fields in the menu_links table which match the table definition in my version of drupal (7.100):

CREATE TABLE `menu_links` (
 `menu_name` varchar(32) NOT NULL DEFAULT '',
 `mlid` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `plid` int(10) unsigned NOT NULL DEFAULT '0',
 `link_path` varchar(255) NOT NULL DEFAULT '',
 `router_path` varchar(255) NOT NULL DEFAULT '',
 `link_title` varchar(255) NOT NULL DEFAULT '',
 `options` blob COMMENT 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.',
 `module` varchar(255) NOT NULL DEFAULT 'system',
 `hidden` smallint(6) NOT NULL DEFAULT '0',
 `external` smallint(6) NOT NULL DEFAULT '0',
 `has_children` smallint(6) NOT NULL DEFAULT '0',
 `expanded` smallint(6) NOT NULL DEFAULT '0',
 `weight` int(11) NOT NULL DEFAULT '0',
 `depth` smallint(6) NOT NULL DEFAULT '0',
 `customized` smallint(6) NOT NULL DEFAULT '0',
 `p1` int(10) unsigned NOT NULL DEFAULT '0',
 `p2` int(10) unsigned NOT NULL DEFAULT '0',
 `p3` int(10) unsigned NOT NULL DEFAULT '0',
 `p4` int(10) unsigned NOT NULL DEFAULT '0',
 `p5` int(10) unsigned NOT NULL DEFAULT '0',
 `p6` int(10) unsigned NOT NULL DEFAULT '0',
 `p7` int(10) unsigned NOT NULL DEFAULT '0',
 `p8` int(10) unsigned NOT NULL DEFAULT '0',
 `p9` int(10) unsigned NOT NULL DEFAULT '0',
 `updated` smallint(6) NOT NULL DEFAULT '0',
 `language` varchar(12) NOT NULL DEFAULT 'und',
 `i18n_tsid` int(10) unsigned NOT NULL DEFAULT '0',
 PRIMARY KEY (`mlid`),
 KEY `path_menu` (`link_path`(128),`menu_name`),
 KEY `menu_plid_expand_child` (`menu_name`,`plid`,`expanded`,`has_children`),
 KEY `menu_parents` (`menu_name`,`p1`,`p2`,`p3`,`p4`,`p5`,`p6`,`p7`,`p8`,`p9`),
 KEY `router_path` (`router_path`(128))
) ENGINE=MyISAM AUTO_INCREMENT=1242 DEFAULT CHARSET=utf8;

So, I note that the error is correct, there is no field langcode, however there is a field language.  Are these meant to be the same field?  How do I progress past this error? 

I would think I need to change the name of this field in the install script, but am I going to trip up over this again.

NB my drupal website supports two different languages (de and en)

Most helpful answers

Hi. These problems are always hard to pinpoint - you may think it has to do with something specific, to find out that the problem you are seeing is the result of a chain reaction happening for something different. 

This is speculation: at times, when the update script encounters a warning, it will want to report it to the UI and this sometimes can trigger a menu tree rebuild. So, I would investigate why line 2019 is trying to unserialize a stdClass. This should not be happening if the database query that ran right before would have worked properly. 

Do you have a way to insert a breakpoint there using xdebug to check what's happening - why you are getting a stdClass object? I see line 2017 seems to be the first one so far in system.install to do a direct db query to the database. Are you certain you have the right database credentials AND access levels in settings.php? 

Hi VaughnR.  Good sleuthing! Yes, Backdrop's langcode is the equivalent of Drupal's language column. This was changed early on in BAckdrop, and keeps causing lots of headaches, especially when upgrading.

These errors are hard to trace. Something (a contrib module, most likely) is causing the menu tree being built before the column langcode has replaced the column language in the database.

I doubt this is caused in line 2019 of system_update_1018(). The variables table has no relation to the menu_links table. 

So, if you feel adventurous, you can try manually changing language to langcode in the menu_items table in your database. system_update_1064() checks to see if the column already exists, so there is no danger of that function barfing because the column already exists.

Otherwise you can start disabling contrib modules one by one in D7, and trying the upgrade again, until it works.

Or, you can try inserting breakpoints (for example, if you use xdebug) in any function that queries/updates the table menu_links and specifically references langcode (e.g. menu_link_save()  or menu_tree_page_data(), etc), and then looking at a backtrace to find out the culprit for the early call. 

Comments

I rummaged through system.install and noted that update_1064() explicitly adds the langcode field to the table menu_links.  Presumably it is being referenced by something before the field gets added.

I did check that the dB user set in settings.php had the correct set of privileges on the database, to ensure that the db_add_field() function would work:

GRANT ALL PRIVILEGES ON `backdrop`.* TO '<db_user>'@'localhost'

Looking through the  config files, I note that system.core.json has the log_ details, but I don't have a system.authorize json file.  I guess this implies that it failed somewhere in update_1018() in fact at line 2019 unserialize($row), so I presume the 'menu_links' table gets referenced in  FROM {variable} by the db_query in the line two above.

Hi VaughnR.  Good sleuthing! Yes, Backdrop's langcode is the equivalent of Drupal's language column. This was changed early on in BAckdrop, and keeps causing lots of headaches, especially when upgrading.

These errors are hard to trace. Something (a contrib module, most likely) is causing the menu tree being built before the column langcode has replaced the column language in the database.

I doubt this is caused in line 2019 of system_update_1018(). The variables table has no relation to the menu_links table. 

So, if you feel adventurous, you can try manually changing language to langcode in the menu_items table in your database. system_update_1064() checks to see if the column already exists, so there is no danger of that function barfing because the column already exists.

Otherwise you can start disabling contrib modules one by one in D7, and trying the upgrade again, until it works.

Or, you can try inserting breakpoints (for example, if you use xdebug) in any function that queries/updates the table menu_links and specifically references langcode (e.g. menu_link_save()  or menu_tree_page_data(), etc), and then looking at a backtrace to find out the culprit for the early call. 

Thanks for your response argiepiano most helpful.

I don't  think it is a contrib module, because I have removed them all from the update (following Jen Lampton's advice in the VUG video 'Upgrading from D7' from 2020).

I will change the field name in menu_links table and see what happens next...

I have just done a little more checking and there seems to be seven tables in the B. dB that still have a 'language' field:

  1. comment
  2. date_format_locale
  3. locales_target
  4. menu_custom
  5. menu_links
  6. node
  7. users

Do all of these tables get the field renamed?  Should I change all of them while I am at it?

OK, changed the field name in 'menu_links' to langcode.

Now two more errors in watchdog, the first is the fatal one, the other one probably occurred before I hit the update button:

| 2024-03-12 17:00:43 | php  | a:6:{s:5:"%type";s:9:"TypeError";s:8:"!message";s:73:"unserialize(): Argument #1 ($data) must be of type string, stdClass given";s:9:"%function";s:13:"unserialize()";s:5:"%file";s:54:"backdrop/core/modules/system/system.install";s:5:"%line";i:2019;s:14:"severity_level";i:3;}           | http://dev.localhost/core/update.php?op=selection&token=C1FFt8RXxLFiGeq7... | http://dev.localhost/core/update.php?op=selection&token=C1FFt8RXxLFiGeq7... |


| 2024-03-12 17:00:18 | php  | a:6:{s:5:"%type";s:7:"Warning";s:8:"!message";s:36:"Undefined array key "update_success"";s:9:"%function";s:21:"update_results_page()";s:5:"%file";s:35:"backdrop/core/update.php";s:5:"%line";i:217;s:14:"severity_level";i:4;} 

Hi. These problems are always hard to pinpoint - you may think it has to do with something specific, to find out that the problem you are seeing is the result of a chain reaction happening for something different. 

This is speculation: at times, when the update script encounters a warning, it will want to report it to the UI and this sometimes can trigger a menu tree rebuild. So, I would investigate why line 2019 is trying to unserialize a stdClass. This should not be happening if the database query that ran right before would have worked properly. 

Do you have a way to insert a breakpoint there using xdebug to check what's happening - why you are getting a stdClass object? I see line 2017 seems to be the first one so far in system.install to do a direct db query to the database. Are you certain you have the right database credentials AND access levels in settings.php? 

Thanks argiepiano for your help with this.

I have logged into mysql using the same credentials as in settings.php and run the query on l.2017 which returns the following.

mysql> SELECT name, value FROM variable WHERE name LIKE 'authorize_filetransfer_connection_settings_%';
+------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| name                                           | value                                                                                                    |
+------------------------------------------------+----------------------------------------------------------------------------------------------------------+
| authorize_filetransfer_connection_settings_ssh | a:2:{s:8:"username";s:4:"root";s:8:"advanced";a:2:{s:8:"hostname";s:9:"localhost";s:4:"port";s:2:"22";}} |
+------------------------------------------------+----------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

So it seems to me that the database is returning a string.

I do not want to install xdebug on my web-server and I really dont want to set up a whole new dev environment to work on this.  I was hoping I could just run a localhost dev site to do the whole job.

This is the third time I have tried to port my D7 web-site to backdrop - the first time in 2019 -  and I have to say that each time it justs gets too difficult and so I stop.  After spending numerous days trying to do this and getting nowhere, it is getting to that time again. 

VaughnR I'm sorry you are having a difficult time with the Drupal upgrade. Upgrading from D7 can be fraught with issues at times, but we are happy to see more and more people are being successful with it.  

I'm open to continue to help you figure this out. Is there a way you could share with me your D7 database? I could test on my end (I have a nice setup to catch these stubborn issues). We could continue the conversation on Zulip as DM. My handler there is @argiepiano

 

Thanks argiepiano,

Thank you for the offer with the database, I may take it up for Ron (as we say in Australia meaning later-on).  I have decided that I should have set up a proper development environment for this and I now have a running backdrop site with no content that I will populate from my production site.  Unfortunately I work on a MacBook and I did not realise that Apple have dropped support for php, so setting it up was far more complex than it was before.

BTW I had no luck finding you on Zulip.

Sure! 

My Zulip handle is @argiepiano