1

두 개의 엔티티 (이벤트 및 사용자)가 있습니다. 각 사용자는 여러 이벤트가 있지만 StructuredProperty 내에 이러한 이벤트가 저장되는 것을 원하지 않습니다. 왜냐하면 나중에 여러 작성자/관리자를 가질 수 있어야하기 때문입니다. 이제는 사용자가 정의 할 이벤트 클래스가 필요하며 그 반대도 마찬가지입니다. 의도 한 구조를 어떻게 구현할 수 있습니까?ndb.Models에서 닭고기 달걀 관계를 해결하는 방법은 무엇입니까?

상호 관계가있는 두 모델입니다.

class Event(EndpointsModel): 
    _message_fields_schema = ("id", "name", "creator", 
         "datetime", "place", "category", "participants") 
    creator = ndb.KeyProperty(kind=User) 
    participants = ndb.KeyProperty(kind=User, repeated=True) 
    name = ndb.StringProperty() 
    datetime = ndb.DateTimeProperty(auto_now_add=True) 
    place = ndb.GeoPtProperty() 
    category = ndb.StringProperty(choices=('all', 'drinking')) 

class User(EndpointsModel): 

    _message_fields_schema = ("id", "name", "password", "events") 

    name = ndb.StringProperty() 
    password = ndb.StringProperty() 
    events = ndb.KeyProperty(kind=Event, repeated=True) 

    def create_event(self, e_name, e_datetime, e_place, e_category): 
     event = Event(name=e_name, creator = self.key, datetime=e_datetime, place=e_place, category=e_category) 
     event.put() 
     self.events.append(event) 
     self.put() 

    def get_events(self): 
     return ndb.get_multi(self.events) 

오류 메시지 :

NameError: name 'User' is not defined

편집 1 : 그렉을 제안처럼 나는, 클래스 이름을 포함하는 문자열로 종류를 변경했습니다. 그러나 그것은 또한 작동하지 않습니다.

ERROR 2014-01-21 09:38:39,764 service.py:191] Encountered unexpected error from ProtoRPC method implementation: BadValueError (Expected Key, got []) 
Traceback (most recent call last): 
    File "/home/chris/Downloads/google_appengine/lib/protorpc-1.0/protorpc/wsgi/service.py", line 181, in protorpc_service_app 
    response = method(instance, request) 
    File "/home/chris/Downloads/google_appengine/lib/endpoints-1.0/endpoints/api_config.py", line 1321, in invoke_remote 
    return remote_method(service_instance, request) 
[...] 
    value = self._call_shallow_validation(value) 
    File "/home/chris/Downloads/google_appengine/google/appengine/ext/ndb/model.py", line 1227, in _call_shallow_validation 
    return call(value) 
    File "/home/chris/Downloads/google_appengine/google/appengine/ext/ndb/model.py", line 1274, in call 
    newvalue = method(self, value) 
    File "/home/chris/Downloads/google_appengine/google/appengine/ext/ndb/model.py", line 1927, in _validate 
    raise datastore_errors.BadValueError('Expected Key, got %r' % (value,)) 
BadValueError: Expected Key, got [] 

답변

2

당신은 개체에 이러한 참조를 만들 수 없습니다 :

class Category(EndpointsModel): 
    _message_fields_schema = ("id", "name", "parent") 
    name = ndb.StringProperty() 
    parent = ndb.KeyProperty(kind='Category', default=None) 

class Event(EndpointsModel): 

    _message_fields_schema = ("id", "name", "creator", "datetime", 
           "place", "category") 

    participants = ndb.KeyProperty(kind='User', repeated=True) 
    creator = ndb.KeyProperty(kind='User') 
    name = ndb.StringProperty() 
    datetime = ndb.DateTimeProperty(auto_now_add=True) 
    place = ndb.GeoPtProperty() 
    category = ndb.KeyProperty(Category) 

class User(EndpointsModel): 

    _message_fields_schema = ("id", "name", "password") 

    name = ndb.StringProperty() 
    password = ndb.StringProperty() 
    events = ndb.KeyProperty(Event, repeated=True) 

지금 나는 다음과 같은 스택 추적을받을 수 있습니다. 여기에 somo 솔루션이 있습니다 : 1. 사용자 인스턴스 에 대해 Event.creator 또는 다른 id에 일반 StringProperty를 사용해야합니다. 2. 클래스 User에서 evens를 제거하십시오. 클래스 이벤트의 인덱스를 사용하여 evens에 접근 할 수 있습니다. 3. 다음과 같은 세 번째 엔티티 모델을 사용하십시오. 이 :

class EventCreator(EndpointsModel): 
    creator = ndb.KeyProperty(kind=User) 
    event = ndb.KeyProperty(kind=Event) 

및 클래스 사용자로부터 클래스 이벤트에서 만든 & 당신은 모델 정의가없는 종류를 참조 할 수의 KeyProperty 생성자에서 문자열을 사용할 수 있습니다

+3

kind를 문자열로 지정하여 순환 의존성을 만들 수있는 다른 클래스를 참조하는 KeyProperty를 만들거나 정의 할 수 있습니다. 다른 대답을 참조하십시오. –

+0

니스, 나도이 기능을 모른다. 고맙습니다. 나는 이것이 최선의 방법이라는 것을. – jacek2v

3

삭제 :

class Event(ndb.Model): 
    participants = ndb.KeyProperty(kind='User', repeated=True) 
+0

좋아,이 소리는 훌륭하지만 작동하지 않는 것 같습니다. * 예외 datastore_errors.BadValueError ('예상 키, % r'% (value,)) % BadValueError : 예상 키, [] * – NaN

+0

먼저 사용자의 인스턴스를 저장 (넣기)해야합니다. 객체가 아닌 키를 할당해야합니다. 즉,'event.participants = some_user.key' 그럼 잘 동작합니다 ;-) –

+0

위의 코드에서'create_event'에서 위의 코드를 실행하면'self.events.append (event.key)' –

1

kind 매개 변수없이 키 속성을 지정할 수 있습니다 (선택 사항). 생성자 또는 미리 입력 된 후크 또는 그와 유사한 것을 수동으로 확인하거나 종류에 대해 걱정할 필요가 없습니다.

class Event(EndpointsModel): 
    creator = ndb.KeyProperty() 

    # Constructor option 
    def __init__(self, *args, **kwargs): 
     super(Event, self).__init__(*args, **kwargs) 
     if 'creator' in kwargs and kwargs['creator'] != 'User': 
      raise Exception('oh no') 

    # Hook option 
    _pre_put_hook(self): 
     if self.creator and self.creator.kind() != 'User': 
      raise Exception("oh no") 

실제 구문은 약간 다를 수 있습니다. 언제든지 편집 할 수 있습니다.

관련 문제