2

HUser 모델 (Google의 User 클래스에서 파생 됨)에는 0 ~ n 개의 소셜 계정 인스턴스가 차례로 포함되어 있습니다. 이 계정은 Facebook, Twitter 또는 LinkedIn 계정에 대한 참조 일 수 있습니다. 나는 Account 모델을 구축하고,이 같은 repeated=TrueUser 모델의 StructuredProperty을 정의 : 난 단지 내 사용자에게 페이스 북이나 링크드 인 계정을 추가하는 경우 예상대로 모든 작품_BaseValue로 저장된 StructuredProperty의 새 항목

class Account(ndb.Expando): 
    account_type = ndb.StringProperty(required=True, choices=['fb', 'tw', 'li']) 
    account_id = ndb.StringProperty() 
    access_token = ndb.StringProperty() 
    ... 

class HUser(User): 
    email = ndb.StringProperty(required=True, validator=validate_email) 
    created = ndb.DateTimeProperty(auto_now_add=True) 
    accounts = ndb.StructuredProperty(Account, repeated=True) 

. 그러나 이상한 점은 트위터 계정을 추가 할 때마다 동일한 사용자에게 추가하는 모든 후속 계정이 이 아닌 _BaseValue(Account())으로 직접 저장된다는 것입니다.

AttributeError: '_BaseValue' object has no attribute 'account_type'

나는이 _BaseValue 변환이 구글의 NDB 소스 코드에 버그가 있습니다 읽었습니다,하지만 어떻게 내가 그것을 제거 할 수 있습니다 그래서 계정을 인출하려고 내 페이지에, 나는 보통 같은 오류를 얻을? 현재이 예외적 인 해결 방법을 사용하여 예외를 무시하고 있습니다.

if type(account) == _BaseValue: 
    account = account.b_val 
    logging.warn("WARN: %s account %s was of type _BaseValue..." % (account.account_type, account.account_id)) 

감사합니다.

답변

6

어떻게 반복 속성에 액세스하고 있습니까? ndb 모델은 _BaseValue과 같은 속성을 저장하고 불행히도 항상 그런 경우가 아닌 "완벽하게"사용자의 유형 (ndb의 UserValue)으로 변환합니다. 이 때문에 모델 외부에 속성을 저장하는 방법에 대해주의해야합니다. 이것을 고려해보십시오 :

myUser = HUser(...) 
accounts = myUser.accounts 
myUser.put() 
accounts[0] # This is a _BaseValue(Account) 
myUser.accounts[0] # This is an Account 

이것은 ndb 이슈 트래커상의 open bug입니다.

+0

내가 그런 일을하고 있는지 정확히 기억할 수는 없지만 내가 그럴 수도 있습니다. 한편, 다른 문제 (당신이 나에게 여기에서 해결하도록 도왔던) 때문에, 나는 디자인을 바꾸어야했다. 이러한 변화는 특히 트위터 계정을 관리 할 때 내 코드에서'put()'의 양을 크게 줄였다. 내 질문을 게시하기 전에 언급 한 버그를 발견했지만 그 의미와 함축을 이해하지 못했습니다. 당신의 대답은 그것을 조금 더 명확하게합니다. 그래서, tu 요약, 미래에이 문제를 피하기 위해, 나는 로컬 엔티티 * 복사본 * ndb 엔티티에서 일하는 것을 피할 필요가있다, 맞습니까? – Romain

+1

핵심은 ndb ** 속성 **의 로컬 복사본에 대한 작업을 피해야한다는 것입니다. ndb 엔티티에서 속성에 직접 액세스하는 한, 옳은 일을 할 것입니다. –

+0

@PatrickCostello,하지만 엔티티에 조작을 위해 열거 할 키 목록이있는 경우에는 어떻게해야합니까? 예 : for job_key for ndb_file.jobs : job = job_key.get() ...이 코드는 다른 곳에서 작동하지만이 경우에는 작동하지 않습니다. – ericso