Use xx [‘xx ‘] = XX to set field value or does not support field: XXX

Demand:

After the tiem object is created, modify the written table of the original item_ Name value

My item:

class People(scrapy.Item):
    table_name = 'people'
    id = scrapy.Field()
    url_token = scrapy.Field()
    name = scrapy.Field()

Solution:

people = People()
people.__class__.table_name='people_20216'

Source code analysis:

If this is what the item says

table_name= scrapy.Field()

After creation, you can directly assign values in this way, which is normal operation

people = People()

people['table_name'] = 'people_20216'

Situation 1:

But if you write like me:

class People(scrapy.Item):
    table_name = 'people'

In addition, it can be modified as follows:

people[‘table_ name’] = ‘people_ 20216’

You will report an error:

Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\twisted\internet\defer.py", line 662, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "C:\Program Files\Python39\lib\site-packages\scrapy\utils\defer.py", line 150, in f
    return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
  File "E:\codedata\gitee\pySpace\study\npoms\npoms\pipelines.py", line 62, in process_item
    item['table_name'] = item.table_name + "_" + mysql_split_util.current_year_month
  File "C:\Program Files\Python39\lib\site-packages\scrapy\item.py", line 100, in __setitem__
    raise KeyError(f"{self.__class__.__name__} does not support field: {key}")

Corresponding to this section of the original code, the source code covers this:

Case 2:

If you write like this

people.table_ name’= ‘people_ 20216’

You will report an error:

Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\site-packages\twisted\internet\defer.py", line 662, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "C:\Program Files\Python39\lib\site-packages\scrapy\utils\defer.py", line 150, in f
    return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
  File "E:\codedata\gitee\pySpace\study\npoms\npoms\pipelines.py", line 63, in process_item
    item.set_table_name(table_name)
  File "E:\codedata\gitee\pySpace\study\npoms\npoms\items.py", line 66, in set_table_name
    self.table_name = table_name
  File "C:\Program Files\Python39\lib\site-packages\scrapy\item.py", line 112, in __setattr__
    raise AttributeError(f"Use item[{name!r}] = {value!r} to set field value")
AttributeError: Use item['table_name'] = 'people_202106' to set field value

Corresponding to this section of the original code, the source code also has corresponding interception:

At this time, we need to look at the creation phase of the source code object

The object creation phase is divided into fields and classes, which we can use above__ setitem__ Method to modify the object in fields. So we need to get the class object and modify the values of the properties in the class.


Read More: