AttributeError:'list'对象在App Engine中没有属性'has_key'

时间:2012-02-01 00:21:36

标签: python google-app-engine

我在使用应用引擎的批量加载器时遇到了一些问题。下面我插入了bulkloader.yaml,hs_transformers.py和错误日志。有什么想法产生这个错误?如果我返回一个实体(只是一个实体,而不是一个包含一个实体的列表,也会抛出错误),我的hs_transformer函数就可以工作了,但是当我尝试返回一个实体列表时会发生这个错误。根据app引擎的文档,我应该能够返回一个实体列表。

.yaml文件:

python_preamble:
- import: re
- import: base64
- import: google.appengine.ext.bulkload.transform
- import: google.appengine.ext.bulkload.bulkloader_wizard
- import: google.appengine.ext.db
- import: google.appengine.api.datastore
- import: hs_transformers
- import: datetime


transformers:

- kind: HBO
  connector: csv

  property_map:
    - property: __key__
      external_name: swfServerID
      import_transform: hs_transformers.string_null_converter

    - property: IP_address
      external_name: IP
      import_transform: hs_transformers.string_null_converter 

    - property: name
      external_name: swfServer
      import_transform: hs_transformers.swf_server_converter

    - property: last_checkin_date
      external_name: clockStampOfLastCheckin
      import_transform: hs_transformers.clock_stamp_of_last_checkin_converter

#    - property: last_update
#      external_name: clockStampOfLastUpdate
#      import_transform: transform

    - property: form_factor
      external_name: formFactor
      import_transform: hs_transformers.string_null_converter

    - property: serial_number
      external_name: serialNumber
      import_transform: hs_transformers.string_null_converter

    - property: allow_reverse_SSH
      external_name: allowReverseSSH
      import_transform: hs_transformers.boolean_converter

    - property: insight_account
      external_name: FK_insightAccountID
      import_transform: hs_transformers.integer_converter

    - property: version
      external_name: ver
      import_transform: hs_transformers.string_null_converter

  post_import_function: hs_transformers.post_hbo 

hs_transformers.py

def post_hbo(input_dict, entity_instance, bulkload_state):  
    return_entities = []

    model_key = db.Key.from_path("Contact", 1)
    logging.error("MODEL KEY " +str(model_key))
    logging.error("MODEL KEY TYPE " +str(type(model_key)))
    keys = db.allocate_ids(model_key, 1)
    logging.error("KEYS " +str(keys))
    logging.error("KEYS TYPE " +str(type(keys)))
    id = keys[0]
    logging.error("ID " +str(id))
    logging.error("ID TYPE " +str(type(id)))

    contact_key = db.Key.from_path("Contact", id)
    logging.error("CONTACT KEY " +str(contact_key))
    logging.error("CONTACT KEY TYPE " +str(type(contact_key)))
    hbo_key =  db.Key.from_path("HBO", input_dict["swfServerID"])
    logging.error("HBO KEY " +str(hbo_key))
    logging.error("HBO KEY TYPE " +str(type(hbo_key)))

    contact = Contact(key=contact_key)

    map = HBOContact()
    map.hbo = hbo_key
    map.contact = contact_key

    return_entities.append(contact)
    return_entities.append(map)

    logging.error("CONTACT KEY AGAIN? " +str(contact.key()))
    logging.error("CONTACT TYPE " +str(type(contact)))
    logging.error("MAP TYPE " +str(type(map)))

    logging.error("RETURN LIST " + str(return_entities))

    return return_entities

最后

Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\Jack Frost>cd..

C:\Users>cd..

C:\>cd "Program Files (x86)"

C:\Program Files (x86)>cd "Google App Engine SDK"

C:\Program Files (x86)\Google App Engine SDK>python appcfg.py upload_data --url=http://bulkloader-testing.appspot.com/remote_api --config_file="C:\Users\Jack Frost\Eclipse Workspace\Headsprout\GAE 1.27.2012\src\utilities\bulkloader\bulkloader.yaml" --filename="C:\Users\Jack Frost\Eclipse Workspace\Headsprout\GAE 1.27.2012\src\utilities\bulkloader\csv_files\smallhbos.csv" --kind=HBO
Uploading data records.
[INFO    ] Logging to bulkloader-log-20120131.160426
[INFO    ] Throttling transfers:
[INFO    ] Bandwidth: 250000 bytes/second
[INFO    ] HTTP connections: 8/second
[INFO    ] Entities inserted/fetched/modified: 20/second
[INFO    ] Batch Size: 10
[INFO    ] Opening database: bulkloader-progress-20120131.160426.sql3
[INFO    ] Connecting to bulkloader-testing.appspot.com/remote_api
[INFO    ] Starting import; maximum 10 entities per post
2012-01-31 16:04:27,135 ERROR hs_transformers.py:66 type object 'datetime.datetime' has no attribute 'datetime'
2012-01-31 16:04:27,137 ERROR hs_transformers.py:17 MODEL KEY ahRzfmJ1bGtsb2FkZXItdGVzdGluZ3INCxIHQ29udGFjdBgBDA
2012-01-31 16:04:27,138 ERROR hs_transformers.py:18 MODEL KEY TYPE <class 'google.appengine.api.datastore_types.Key'>
2012-01-31 16:04:27,461 ERROR hs_transformers.py:20 KEYS (16031L, 16031L)
2012-01-31 16:04:27,463 ERROR hs_transformers.py:21 KEYS TYPE <type 'tuple'>
2012-01-31 16:04:27,463 ERROR hs_transformers.py:23 ID 16031
2012-01-31 16:04:27,464 ERROR hs_transformers.py:24 ID TYPE <type 'long'>
2012-01-31 16:04:27,466 ERROR hs_transformers.py:27 CONTACT KEY ahRzfmJ1bGtsb2FkZXItdGVzdGluZ3IOCxIHQ29udGFjdBiffQw
2012-01-31 16:04:27,466 ERROR hs_transformers.py:28 CONTACT KEY TYPE <class 'google.appengine.api.datastore_types.Key'>
2012-01-31 16:04:27,467 ERROR hs_transformers.py:30 HBO KEY ahRzfmJ1bGtsb2FkZXItdGVzdGluZ3IKCxIDSEJPIgEzDA
2012-01-31 16:04:27,467 ERROR hs_transformers.py:31 HBO KEY TYPE <class 'google.appengine.api.datastore_types.Key'>
2012-01-31 16:04:27,469 ERROR hs_transformers.py:42 CONTACT KEY AGAIN? ahRzfmJ1bGtsb2FkZXItdGVzdGluZ3IOCxIHQ29udGFjdBiffQw
2012-01-31 16:04:27,469 ERROR hs_transformers.py:43 CONTACT TYPE <class 'shared.datastore.Contact'>
2012-01-31 16:04:27,470 ERROR hs_transformers.py:44 MAP TYPE <class 'shared.datastore.HBOContact'>
2012-01-31 16:04:27,470 ERROR hs_transformers.py:46 RETURN LIST [<shared.datastore.Contact object at 0x0000000003DBBB00>, <shared.datastore.HBOContact object at 0x0000000003DBBC18>]
[ERROR   ] [WorkerThread-0] WorkerThread:
Traceback (most recent call last):
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\tools\adaptive_thread_pool.py", line 176, in WorkOnItems
status, instruction = item.PerformWork(self.__thread_pool)
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\tools\bulkloader.py", line 764, in PerformWork
transfer_time = self._TransferItem(thread_pool)
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\tools\bulkloader.py", line 933, in _TransferItem
self.content = self.request_manager.EncodeContent(self.rows)
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\tools\bulkloader.py", line 1394, in EncodeContent
entity = loader.create_entity(values, key_name=key, parent=parent)
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\ext\bulkload\bulkloader_config.py", line 446, in create_entity
self.__track_max_id(entity)
  File "C:\Program Files (x86)\Google App Engine SDK\google\appengine\ext\bulkload\bulkloader_config.py", line 420, in __track_max_id
elif not entity.has_key():
AttributeError: 'list' object has no attribute 'has_key'
[INFO    ] [WorkerThread-1] Backing off due to errors: 1.0 seconds
[INFO    ] An error occurred. Shutting down...
[ERROR   ] Error in WorkerThread-0: 'list' object has no attribute 'has_key'

[INFO    ] 9 entities total, 0 previously transferred
[INFO    ] 0 entities (2364 bytes) transferred in 1.5 seconds
[INFO    ] Some entities not successfully transferred
  

还以为我会粘贴code.google.com关于post_import_function

的内容      
    
      

post_import_function(input_dict,instance,bulkload_state_copy)functionName

             

您的函数必须返回以下内容之一:无,这意味着跳过导入此记录;单个实体(通常是传入的实例参数);或要导入的多个实体的列表。

    
  
     

当我在post_import_transform函数中注释掉所有代码并且只返回None时,我仍然会得到相同的错误;但是,这与code.google.com相矛盾。

http://code.google.com/appengine/docs/python/tools/uploadingdata.html

1 个答案:

答案 0 :(得分:1)

浏览相关代码,看起来像一个bug。

你的帖子导入功能是在dict_to_entity内运行的,它只返回你的函数返回的内容。 create_entity会将dict_to_entity返回__track_max_id的任何内容提供给App Engine Issue tracker,但这似乎无法正确解释列表或无。

我建议你将其归档为{{3}}中的错误。

请注意,您可以在本地SDK中轻松修复此问题。基本上将__track_max_id更改为:

def __track_max_id(self, entity):
  """Check the entity to see it has a numeric ID higher than any seen so far.

  High IDs are stored in self.high_ids[path-to-entity-kind].
  They are not tracked if self.increment_id is None.

  Args:
    entity: An entity with a key.
  """
  if not self.increment_id:
    return
  if not entity:
    return

  if isinstance(entity, datastore.Entity):
    entities = [entity]
  else:
    entities = entity

  for entity in entities:
    if not entity.key():
      continue
    key = entity.key()
    key_id = key.id()
    if not key_id:
      continue
    path = tuple(key.to_path()[:-1])
    if self.high_ids.get(path, 0) < key_id:
      self.high_ids[path] = key_id