NDB 모델 클래스

Model 클래스에서 상속받은 클래스는 Datastore에 저장된 항목의 구조를 나타냅니다. 애플리케이션은 모델 클래스를 정의하여 항목의 구조를 표시한 다음 해당 모델 클래스를 인스턴스화하여 항목을 만듭니다. 모든 모델 클래스가 직접 또는 간접적으로 Model로부터 상속받아야 합니다.

이 페이지에는 API 참조 문서가 있습니다. 개요는 NDB 항목 및 키를 참조하세요.

소개

Model로부터 상속받는 클래스는 Datastore 항목을 설명합니다.

모든 모델 클래스는 Model에서 직접 또는 간접적으로 상속받아야 합니다. 모델 클래스 정의에서 간단하게 할당하여 모델의 구조를 선언할 수 있습니다.

from google.appengine.ext import ndb

class Person(ndb.Model):
  name = ndb.StringProperty()
  age = ndb.IntegerProperty()

이제 Person 항목을 만들어 Datastore에 쓸 수 있습니다.

p = Person(name='Arthur Dent', age=42)
k = p.put()

put()의 반환 값은 나중에 동일한 항목을 검색하는 데 사용할 수 있는 입니다.

p2 = k.get()
p2 == p  # Returns True

항목을 업데이트하려면 해당 속성을 변경하고 다시 쓰기만 하면 됩니다. 이렇게 해도 키는 변경되지 않습니다.

p2.name = 'Arthur Philip Dent'
p2.put()

키를 사용하여 항목을 삭제할 수도 있습니다.

k.delete()

클래스 본문에 있는 속성 정의는 Datastore에 저장할 필드의 이름 및 유형, 이러한 필드의 색인을 생성해야 하는지 여부, 해당 기본값 등을 시스템에 알려줍니다. 여러 가지 다양한 속성 유형이 존재합니다.

종류는 일반적으로 클래스 이름과 같습니다(모듈 이름 또는 기타 상위 범위는 제외). 종류를 재정의하려면(스키마 변경에 유용) _get_kind()라는 클래스 메서드를 다음과 같이 정의합니다.

  class MyModel(ndb.Model):
    @classmethod
    def _get_kind(cls):
      return 'AnotherKind'

애플리케이션은 두 모델 클래스가 서로 다른 모듈에 있더라도 동일한 종류로 정의하면 안 됩니다. 애플리케이션의 종류는 전역 '네임스페이스'로 간주됩니다.

Model 서브클래스는 대부분의 작업(get, put, delete, allocate_ids)에 호출 전 및 호출 후 후크를 정의할 수 있습니다.

생성자

애플리케이션은 일반적으로 Model()을 호출하지 않지만 Model로부터 상속받은 클래스의 생성자를 호출할 가능성이 높습니다. 그 결과 모델의 새로운 인스턴스가 생성되며 이를 항목이라고도 합니다.

새로 생성된 항목은 Datastore에 자동으로 작성되지 않습니다. 이를 수행하려면 put()에 대한 명시적 호출을 사용하여 Datastore에 기록되어야 합니다.

인수:

Model 서브클래스는 다음과 같은 키워드 인수를 지원합니다.

key
이 모델의
인스턴스입니다. key 매개변수를 사용할 경우 idparent는 반드시 None(기본값)이어야 합니다.
id
이 모델의 키 ID입니다. id를 사용할 경우 키는 None(기본값)이어야 합니다.
parent
상위 모델의 인스턴스 또는 최상위 수준 모델의 None입니다. parent를 사용하는 경우 keyNone여야 합니다.
namespace
이 항목에 사용할 네임스페이스이거나 현재 네임스페이스를 사용할 경우 None(기본값)입니다. namespace를 사용하는 경우 keyNone여야 합니다.

애플리케이션은 모델 속성에 대한 키워드 인수 매핑을 사용할 수도 있습니다. 예를 들어 다음을 사용할 수 있습니다.

class Person(ndb.Model):
  name = StringProperty()
  age = IntegerProperty()

p = Person(name='Arthur Dent', age=42)

'key', 'id', 'parent', 'namespace' 속성은 쉽게 정의할 수 없습니다. 예를 들어 생성자 또는 populate() 호출에서 key="foo"를 전달할 경우 이 함수는 'key' 속성이 아닌 항목 키를 설정합니다.

참고: Model 서브클래스에서 생성자를 재정의하면 경우에 따라 생성자도 암시적으로 호출되기 때문에 해당 호출도 지원해야 합니다. Datastore에서 항목이 읽히면 먼저 인수 없이 생성자를 호출하여 빈 항목이 생성되고 그 이후에 키 및 속성 값이 하나씩 설정됩니다. get_or_insert() 또는 get_or_insert_async()가 새 인스턴스를 만들면 **constructor_args를 생성자에 전달하고 나중에 키를 설정합니다.

클래스 메서드

allocate_ids(size=None, max=None, parent=None, **ctx_options)

이 모델 클래스의 키 ID 범위를 할당합니다.

인수

size
할당할 ID 수입니다. size 또는 max를 지정할 수 있으며 둘 다 지정할 수는 없습니다.
max
할당할 최대 ID입니다. size 또는 max를 지정할 수 있으며 둘 다 지정할 수는 없습니다.
parent
ID가 할당될 상위 키입니다.
**ctx_options
컨텍스트 옵션

할당된 범위에 대해 (start, end)가 있는 튜플을 반환합니다.

애플리케이션은 트랜잭션에서 allocate_ids()를 호출할 수 없습니다.

allocate_ids_async(size=None, max=None, parent=None, **ctx_options)

allocate_ids의 비동기 버전입니다.

할당된 범위에 대해 (start, end)가 있는 튜플이 결과인 Future 객체를 반환합니다.

get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
ID별로 항목을 반환합니다. 이는 단지 Key(cls, id).get()의 약칭입니다.

인수

id
문자열 또는 정수 키 ID입니다.
parent
가져올 모델의 상위 키입니다.
app(키워드 인수)
앱의 ID입니다. 지정하지 않으면 현재 앱의 데이터를 가져옵니다.
namespace(키워드 인수)
네임스페이스입니다. 값을 지정하지 않으면 기본 네임스페이스의 데이터를 가져옵니다.
**ctx_options
컨텍스트 옵션

모델 인스턴스를 반환하거나 찾을 수 없는 경우 None을 반환합니다.

get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
get_by_id의 비동기 버전입니다.

결과가 모델 인스턴스인 Future 객체를 반환하거나 찾을 수 없는 경우 None을 반환합니다.

get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
기존 항목을 트랜잭션 방식으로 검색하거나 새 항목을 만듭니다.

인수

key_name
검색하거나 만들 키 이름(문자열 키 ID)입니다.
parent
상위 항목 키입니다(있는 경우).
app
앱의 ID입니다. 지정하지 않으면 현재 앱의 데이터를 가져옵니다.
namespace
네임스페이스입니다. 값을 지정하지 않으면 기본 네임스페이스의 데이터를 가져옵니다.
context_options
컨텍스트 옵션

지정된 키 이름의 인스턴스가 아직 존재하지 않는 경우 이 함수는 키워드 인수도 모델 클래스의 생성자에 전달합니다. 제공된 key_name 및 상위 요소를 사용하는 인스턴스가 이미 있으면 이 인수가 삭제됩니다.

지정된 키 이름 및 상위 요소를 사용하는 Model 클래스의 기존 인스턴스를 반환하거나 방금 만든 새 인스턴스를 반환합니다.

이 함수는 트랜잭션을 사용합니다. 이 함수를 호출하는 코드가 이미 트랜잭션에 있는 경우 이 함수는 기존 트랜잭션을 재사용하려고 시도합니다. 이 함수의 항목 그룹이 기존 트랜잭션과 호환되지 않는 경우에는 오류가 발생할 수 있습니다.

get_or_insert_async(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)

get_or_insert의 비동기 버전입니다.

지정된 키 이름과 상위 요소를 사용하는 Model 클래스의 기존 인스턴스가 결과인 Future 객체를 반환하거나 방금 만든 새 인스턴스를 반환합니다.

query([filter1, filter2, ...,] ancestor=None, app=None, namespace=None, filters=None, orders=None, default_options=None, projection=None distinct=False group_by=None)

쿼리의 설명대로 이 클래스의 Query 객체를 만듭니다.

distinct 키워드 인수는 group_by = projection의 약자입니다. 다른 모든 키워드 인수는 쿼리 생성자에 전달됩니다.

위치 인수를 지정하면 해당 인수가 초기 필터를 설정하는 데 사용됩니다.

Query 객체를 반환합니다.

인스턴스 메서드

populate(**constructor_options)

항목 속성의 값을 설정합니다. 해당 키워드 인수는 생성자와 동일한 방식으로 속성 이름을 자동으로 인식합니다.

put(**ctx_options)

항목의 데이터를 Datastore에 씁니다. 항목의 를 반환합니다.

인수

**ctx_options
컨텍스트 옵션
put_async(**ctx_options)

항목의 데이터를 Datastore에 비동기식으로 씁니다. Future 객체를 반환합니다. Future 객체의 결과는 항목 입니다.

인수

**ctx_options
컨텍스트 옵션
to_dict(include=all, exclude=None)

모델 속성 값이 포함된 dict를 반환합니다. StructuredPropertyLocalStructuredProperty의 속성 값은 재귀적으로 사전으로 변환됩니다.

인수:

include
포함할 속성의 선택적 목록입니다. 기본값은 all입니다.
exclude
제외할 속성의 선택적 목록입니다. includeexclude가 겹치는 경우 exclude가 적용됩니다.

참고: 속성 값이 변경 가능한 객체인 경우(예: 반복 속성을 나타내는 목록 또는 JsonProperty에 저장된 사전 또는 목록) 값이 명시적으로 변환되지 않는 한(예: StructuredProperty) 동일한 객체가 항목에 저장된 사전에 반환됩니다. 이 경우 사전을 변경하면 항목도 변경됩니다. 반대의 경우도 마찬가지입니다.

인스턴스 데이터

key
Model 키를 저장할 특수 속성입니다.

후크 메서드

애플리케이션에서 Model의 서브클래스는 이러한 메서드 중 하나 이상을 사전 작업 또는 사후 작업 '후크' 메서드로 정의할 수 있습니다. 예를 들어 각 'get' 전에 몇몇 코드를 실행하려면 모델 서브클래스 _pre_get_hook() 메서드를 정의합니다. 후크 함수를 작성하는 방법에 대한 자세한 내용은 모델 후크를 참조하세요.

@classmethod
_pre_allocate_ids_hook(cls, size, max, parent)
allocate_ids() 이전에 실행되는 후크
@classmethod
_post_allocate_ids_hook(cls, size, max, parent, future)
allocate_ids() 이후에 실행되는 후크
@classmethod
_pre_delete_hook(cls, key)
delete() 이전에 실행되는 후크
@classmethod
_post_delete_hook(cls, key, future)
delete() 이후에 실행되는 후크
@classmethod
_pre_get_hook(cls, key)
이 모델 항목을 가져올 경우 Key.get() 이전에 실행되는 후크
@classmethod
_post_get_hook(cls, key, future)
이 모델 항목을 가져올 경우 Key.get() 이후에 실행되는 후크
_pre_put_hook(self)
put() 이전에 실행되는 후크
_post_put_hook(self, future)
put() 이후에 실행되는 후크

점검

이 메소드를 사용하여 지정된 모델의 속성과 구성을 점검할 수 있습니다. 여러 유형의 모델을 허용하는 라이브러리나 함수를 작성하는 경우에 유용합니다.

종류별로 찾기

모든 모델에는 재정의되지 않는 한 일반적으로 클래스 이름과 동일한 종류가 있습니다. 이 종류를 사용하면 _lookup_model을 사용하여 연결된 모델 클래스를 찾을 수 있습니다.

class Animal(ndb.Model):
    type = ndb.StringProperty()

print Animal._get_kind()  # 'Animal'
print ndb.Model._lookup_model('Animal')  # class Animal

_lookup_model은 애플리케이션에서 이미 가져온 모델 클래스에서만 작동합니다.

속성

_properties를 사용하여 모델과 연결된 모든 속성의 목록을 가져올 수 있습니다.

class User(ndb.Model):
    name = ndb.StringProperty()
    email = ndb.StringProperty()

print User._properties
# {'email': StringProperty('email'), 'name': StringProperty('name')}

_propertiesExpando 인스턴스에서 작동합니다.

class Example(ndb.Expando):
  pass

e = Example()
e.foo = 1
e.bar = 'blah'
e.tags = ['exp', 'and', 'oh']
print e._properties
# {'foo': GenericProperty('foo'), 'bar': GenericProperty('bar'),
# 'tags': GenericProperty('tags', repeated=True)}

속성 인스턴스를 점검할 수 있습니다. 생성자에 제공되는 옵션_ 프리픽스가 붙은 속성으로 사용할 수 있습니다.

print User._properties['email']._name  # 'email'
print User._properties['email']._required  # False
print User._properties['email']._default  # None
print User._properties['email']._choices  # None
print User._properties['email']._compressed  # False
print User._properties['email']._indexed  # True
print User._properties['email']._compressed  # False
print User._properties['email']._repeated  # False
print User._properties['email']._verbose_name  # None
print isinstance(User._properties['email'], ndb.StringProperty)  # True

메서드 별칭

Model 클래스의 모든 메서드에는 _ 프리픽스가 붙는 별칭이 있습니다. 예를 들어 _put()put()와 동일합니다. 따라서 항상 _ 프리픽스가 붙는 메서드를 사용할 경우 메서드 이름과 충돌하는 이름이 지정된 속성이 발생할 수 있습니다. 하지만 생성자에 key, parent 또는 id라는 이름을 가진 속성을 지정할 수는 없습니다.

class MyModel(ndb.Model):
    put = ndb.StringProperty()
    query = ndb.StringProperty()
    key = ndb.StringProperty()

entity = MyModel()
entity.put = '1'
entity.query = '2'
entity.key = '3'

entity._put()
print entity
# MyModel(key=Key('MyModel', ...), put=u'1', query=u'2', key=u'3')

print MyModel._query().fetch()
# same as above.

임의 모델과 상호작용하는 타사 라이브러리를 만드는 경우 _ 프리픽스가 붙은 메서드를 사용하는 것이 좋습니다.