2011-08-27 1 views
0

지금이 작업을 수행하는 데 적어도 2 시간을 소비했습니다. SO과 Google 그룹스에서 꽤 많이 다른 질문을 보았습니다. 그러나 그 답변 중 아무 것도 저에게 효과가없는 것 같습니다.AppEngine bulkloader가 key_name을 설정하여 항목을 업로드합니다.

질문 : 아래 CSV 파일의 데이터를 데이터 저장소에 일괄 업로드하여 CSV 파일에 key_name이 정의 된 엔티티를 만드는 방법 (아래의 추가 기능 사용과 동일한 결과) 위의 코드 make_key 단순히 도메인 소문자를하게하고 앞에 추가로 :

def add(domains): 
    """ 
    Add domains. This functions accepts a single domain string or a 
    list of domain strings and adds them to the database. The domain(s) 
    must be valid unicode strings (a ValueError is thrown if the domain 
    strings are not valid. 
    """ 
    if not isinstance(domains, list): 
     domains = [domains] 

    cleaned_domains = [] 
    for domain in domains: 
     clean_domain_ = clean_domain(domain) 
     is_valid_domain(clean_domain_) 
     cleaned_domains.append(clean_domain_) 

    domains = cleaned_domains 

    db.put([RegisteredDomain(key_name=make_key(domain)) for domain in domains]) 


def get(domains): 
    """ 
    Get domains. This function accepts a single domain string or a list 
    of domain strings and queries the database for them. It returns a 
    dictionary containing the domain name and RegisteredDomain object or 
    None if the entity was not found. 
    """ 
    if not isinstance(domains, list): 
     domains = [domains] 

    entities = db.get([Key.from_path('RegisteredDomain', make_key(domain)) for domain in domains]) 
    return dict(zip(domains, entities)) 

참고 :

여기
class RegisteredDomain(db.Model): 
    """ 
    Domain object class. It has no fields because it's existence is 
    proof that it has been registered. Indivdual registered domains 
    can be found using keys. 
    """ 
    pass 

내가 보통/삭제 도메인 등을 추가하는 방법은 다음과 같습니다

내 모델입니다 '디'.

그래서 저기 있습니다. 이제 CSV 파일에서 일부 RegisteredDomain 항목을 업로드하는 데 미쳐 가고 있습니다. 여기에 CSV 파일 (첫 번째 문자 'D'를 참고로 인해 키 이름이 숫자로 시작되지 않을 수 있다는 사실이있다)이다 : 나는 수 없었다

key 
dgoogle.com 
dgoogle11.com 
dfacebook.com 
dcool.com 
duuuuuuu.com 
dsdsdsds.com 
dffffooo.com 
dgmail.com 

bulkloader의 YAML을 자동 생성 파일은 앱 엔진이 아직 내 데이터 저장소 통계를 업데이트하지 않기 때문에 (1 일 플러스 몇 시간). 그래서이 (그리고 많은 유사한 순열은) 내가 (대부분 import_transform 비트 변경)과 함께 온 것입니다 : 나는 그것을 업로드하려고 어떤 이유로 지금

python_preamble: 
- import: google.appengine.ext.bulkload.transform 
- import: google.appengine.api.datastore 
- import: google.appengine.ext.db 
- import: utils 
- import: bulk_helper 

transformers: 
- kind: RegisteredDomain 
    connector: csv 
    connector_options: 
    encoding: utf-8 
    property_map: 
    - property: __key__ 
     external_name: key 
     export_transform: bulk_helper.key_to_reverse_str 
     import_template: transform.create_foreign_key('RegisteredDomain') 

을 모두 잘가는 것을 말한다 및 X 개체가왔다 등을 전송하지만 데이터 저장소에서 아무 것도 업데이트되지 않습니다 (관리 콘솔에서 볼 수있는 것처럼).

appcfg.py upload_data --application=domain-sandwich --kind=RegisteredDomain --config_file=bulk.yaml --url=http://domain-sandwich.appspot.com/remote_api --filename=data.csv 

그리고 마침내 내 데이터 저장소 뷰어 모습입니다 : 여기에 내가 업로드하는 방법입니다 Datastore Viewer

참고 : I 작동 어떤 (dev에 서버와 애플리케이션 엔진에 모두이 일을하고있다 ..).

도움 주셔서 감사합니다.

답변

0

문제는 appengine bulkloader (또는 datastore API)의 버그입니다. 나는이 문제 (issue 1, issue 2, issue 3, issue 4)에 대한 몇 가지 문제를 게시하지만, 여기에 나중에 참조 할 수 있도록 bulkloader 오류에 대한 텍스트 경우 : bulkloader는 등록없이 모델을 가져 오지 않습니다

VERSION: 
release: "1.5.2" 
timestamp: 1308730906 
api_versions: ['1'] 

. 예 :이 같은 이들 엔티티를 사용할 수있는 응용 프로그램에서

class MetaObject(db.Model): 
    """ 
    Property-less object. Identified by application set key. 
    """ 
    pass 

: 나는 bulkloader를 사용하여 데이터를 가져올 시도 할 때

db.put([MetaObject(key_name=make_key(obj)) for obj in objs]) 
db.get([Key.from_path('MetaObject', make_key(obj)) for obj in objs]) 
db.delete([Key.from_path('MetaObject', make_key(obj)) for obj in objs]) 

지금 문제가 발생했습니다.

1365 def EncodeContent(self, rows, loader=None): 
1366  """Encodes row data to the wire format. 
1367 
1368  Args: 
1369  rows: A list of pairs of a line number and a list of column values. 
1370  loader: Used for dependency injection. 
1371 
1372  Returns: 
1373  A list of datastore.Entity instances. 
1374 
1375  Raises: 
1376  ConfigurationError: if no loader is defined for self.kind 
1377  """ 
1378  if not loader: 
1379  try: 
1380   loader = Loader.RegisteredLoader(self.kind) 
1381  except KeyError: 
1382   logger.error('No Loader defined for kind %s.' % self.kind) 
1383   raise ConfigurationError('No Loader defined for kind %s.' % self.kind) 
1384  entities = [] 
1385  for line_number, values in rows: 
1386  key = loader.generate_key(line_number, values) 
1387  if isinstance(key, datastore.Key): 
1388   parent = key.parent() 
1389   key = key.name() 
1390  else: 
1391   parent = None 
1392  entity = loader.create_entity(values, key_name=key, parent=parent) 
1393 
1394  def ToEntity(entity): 
1395   if isinstance(entity, db.Model): 
1396   return entity._populate_entity() 
1397   else: 
1398   return entity 
1399 
1400  if not entity: 
1401 
1402   continue 
1403  if isinstance(entity, list): 
1404   entities.extend(map(ToEntity, entity)) 
1405  elif entity: 
1406   entities.append(ToEntity(entity)) 
1407 
1408  return entities 

(이 일에 대한 문제를 게시 할 예정입니다) 데이터 저장소 엔티티 객체의 서브 클래스가 오버라이드 (override)하지 않고 DICT 때문에 다음 bulkloader 코드를 통해 검토 한 결과, 버그는 EncodeContent의 방법으로 (라인 1,400에서 1,406 사이)에 밝혀졌다 0이 아닌 또는 len 메서드 속성이 없지만 키가있는 엔터티 일 때 true (키가 설정되어 있어도 "엔터티가 아닌 경우 true"로 설정 됨) 엔티티에 추가됩니다.

--- bulkloader.py  2011-08-27 18:21:36.000000000 +0200 
+++ bulkloader_fixed.py 2011-08-27 18:22:48.000000000 +0200 
@@ -1397,12 +1397,9 @@ 
     else: 
      return entity 

-  if not entity: 
- 
-  continue 
     if isinstance(entity, list): 
     entities.extend(map(ToEntity, entity)) 
-  elif entity: 
+  else: 
     entities.append(ToEntity(entity)) 

    return entities 
--- datastore.py  2011-08-27 18:41:16.000000000 +0200 
+++ datastore_fixed.py 2011-08-27 18:40:50.000000000 +0200 
@@ -644,6 +644,12 @@ 

    self.__key = Key._FromPb(ref) 

+ def __nonzero__(self): 
+  if len(self): 
+   return True 
+  if self.__key: 
+   return True 
+ 
    def app(self): 
    """Returns the name of the application that created this entity, a 
    string or None if not set. 

게시 버그 리포트 :

문제 1 : http://code.google.com/p/googleappengine/issues/detail?id=5712

여기

는 (하나 하나가 작동)을 bulkloader에 또는 단체에서 제로를 재정 의하여이를 고정하는 DIFF입니다

2 호 http://code.google.com/p/googleappengine/issues/detail?id=5713

문제 3 : http://code.google.com/p/googleappengine/issues/detail?id=5714

문제 4 : http://code.google.com/p/googleappengine/issues/detail?id=5715

관련 문제