[SOLVED] Upgrade step after adding column to datagrid field

I am trying to add a new column 'article_customer_number' to an existing datagrid field:

class IArticlesListRowSchema(Interface):
    dexteritytextindexer.searchable('article_number')
    articles_color_size_list = schema.Choice(title=_(u'Artikel Farbton / Gebinde'), vocabulary='mdb_theme.ArticlesVocabulary', required=True)
    article_number           = schema.TextLine(title=_(u'Artikelnummer'), required=True, min_length=5, max_length=5)
    article_customer_number  = schema.TextLine(title=_(u'Kunden-Artikelnummer'), required=False, default=u'')

In the edit forms of my existing dexterity content, the datagrid displays the string <NO_VALUE> in each row. To avoid inadvertently saving that string when an editor makes other changes to their content, I want to update my existing content by adding a default value.

In the past, I have successfully updated existing values using the article.update(column_name=value) line below. This does not work for new fields. What am I doing wrong here?

def set_default_customer_article_number(context):
    """ add key/value 'article_customer_number':u'' in articles_list fields.
        remove obsolete 'plentymarkets_variant_id', 'ean_code', 'article_plentymarkets_price'
    """

    catalog = api.portal.get_tool('portal_catalog')
    brains = catalog(portal_type=['produkte'])

    product_count = 0
    article_count = 0

    keys_to_remove = ['plentymarkets_variant_id', 'ean_code', 'article_plentymarkets_price']
    key_to_add = {'article_customer_number': u''}

    for brain in brains:
        obj = brain.getObject()
        articles_list = obj.articles_list
        product_count += 1
        if articles_list:
            for article in articles_list:
                for key in keys_to_remove:
                    if key in article.keys():
                        del article[key]
                article.update(key_to_add)
                article_count += 1
                log.info(article)
            obj.reindexObject()


    log.info('%s %s products updated' % (get_linenumber(), product_count))
    log.info('%s articles updated.' % article_count)

Looks like I ran into a crufty catalog entry:

Traceback (innermost last):
  Module ZPublisher.Publish, line 146, in publish
  Module Zope2.App.startup, line 303, in commit
  Module transaction._manager, line 131, in commit
  Module transaction._transaction, line 295, in commit
  Module transaction._transaction, line 366, in _callBeforeCommitHooks
  Module Products.CMFCore.indexing, line 310, in before_commit
  Module Products.CMFCore.indexing, line 220, in process
  Module Products.CMFCore.indexing, line 46, in reindex
  Module Products.CMFCore.CatalogTool, line 359, in _reindexObject
  Module Products.CMFPlone.CatalogTool, line 422, in catalog_object
  Module Products.ZCatalog.ZCatalog, line 476, in catalog_object
  Module Products.ZCatalog.Catalog, line 360, in catalogObject
  Module Products.PluginIndexes.common.UnIndex, line 216, in index_object
  Module Products.PluginIndexes.common.UnIndex, line 242, in _index_object
  Module Products.PluginIndexes.common.UnIndex, line 193, in insertForwardIndexEntry
  Module functools, line 56, in <lambda>
  Module z3c.relationfield.relation, line 87, in __lt__
AttributeError: 'str' object has no attribute 'from_attribute'

End of story: I made my code slightly more explicit, FWIW this worked for me...

    for brain in brains:
        obj = brain.getObject()
        if obj.articles_list:
            articles_list = list(obj.articles_list)
            product_count += 1
            for article in articles_list:
                for key in keys_to_remove:
                    if key in article.keys():
                        del article[key]
                article.update(key_to_add)
                article_count += 1
            obj.articles_list = list(articles_list)
            try:
                obj.reindexObject()
            except AttributeError:
                log.info('Error reindexing %s' % obj.getId())

Plone Foundation Code of Conduct