항목 속성 참조

Datastore 모드의 Firestore(Datastore)는 다양한 속성 값 데이터 유형을 지원합니다. 여기에는 다음이 포함됩니다.

  • 정수
  • 부동 소수점 수
  • 문자열
  • 날짜
  • 바이너리 데이터

전체 유형 목록은속성 및 값 유형을 참조하세요.

속성 및 값 유형

항목과 연관된 데이터 값은 하나 이상의 속성으로 구성됩니다. 각 속성에는 이름과 하나 이상의 값이 있습니다. 속성에는 둘 이상의 유형 값이 있을 수 있으며, 두 개의 항목에 동일한 속성의 서로 다른 유형 값이 있을 수 있습니다. 속성은 색인 생성되거나 색인 생성되지 않을 수 있으며, 속성 P를 기준으로 정렬 또는 필터링하는 쿼리는 P가 색인 생성되지 않은 항목을 무시합니다. 항목 하나에 포함될 수 있는 색인 생성된 속성은 최대 20,000개입니다.

지원되는 값 유형은 다음과 같습니다.

쿼리에 혼합 유형 값이 있는 필드가 있으면 Datastore는 내부 표시를 기준으로 확정된 순서를 사용합니다.

  1. Null 값
  2. 고정 소수점 수
    • 정수
    • 날짜 및 시간
  3. 부울 값
  4. 바이트 시퀀스
    • 유니코드 문자열
    • Blobstore 키
  5. 부동 소수점 수
  6. Datastore 키

긴 텍스트 문자열 및 긴 바이트 문자열 에 색인이 생성되지 않았으므로 정의된 순서가 없습니다.

속성 유형

NDB에서는 다음과 같은 속성 유형이 지원됩니다.

속성 유형 설명
IntegerProperty 부호 있는 64비트 정수
FloatProperty 배정밀도 부동 소수점 수
BooleanProperty 부울
StringProperty 색인이 생성된 최대 1500바이트의 유니코드 문자열
TextProperty 색인이 생성되지 않은 무제한 길이의 유니코드 문자열
BlobProperty 해석되지 않은 바이트 문자열:
indexed=True를 설정한 경우 색인이 생성된 최대 1500바이트의 문자열
indexedFalse인 경우(기본값) 색인이 생성되지 않은 무제한 길이 문자열
(선택사항) 키워드 인수:compressed.
DateTimeProperty 날짜 및 시간(날짜 및 시간 속성 참조)
DateProperty 날짜(날짜 및 시간 속성 참조)
TimeProperty 시간(날짜 및 시간 속성 참조)
GeoPtProperty 지리적 위치. ndb.GeoPt 객체입니다. 이 객체에는 모두 부동 소수점인 latlon 속성이 있습니다. ndb.GeoPt(52.37, 4.88)와 같은 부동 소수점 2개 또는 ndb.GeoPt("52.37, 4.88") 문자열을 사용하여 객체를 생성할 수 있습니다. (실제로는 db.GeoPt와 동일한 클래스)
KeyProperty Datastore 키
선택적 키워드 인수: kind=kind. 이 속성에 할당된 키에는 항상 표시된 종류가 포함되어야 합니다. 문자열 또는 모델 서브클래스일 수 있습니다.
BlobKeyProperty Blobstore 키
이전 db API의 BlobReferenceProperty에 해당하지만 속성 값이 BlobInfo 대신 BlobKey입니다. BlobInfo(blobkey)를 사용하여 BlobInfo를 생성할 수 있습니다.
UserProperty 사용자 객체
StructuredProperty 값에 따라 다른 모델 내에서 한 종류의 모델을 포함합니다(구조화된 속성 참조).
LocalStructuredProperty StructuredProperty와 비슷하지만 디스크 상 표현이 불투명 blob이고 색인이 생성되지 않습니다(구조화된 속성 참조).
선택적 키워드 인수: compressed.
JsonProperty 값은 Python의 json 모듈을 사용하여 직렬화할 수 있는 Python 객체(예: 목록, 사전 또는 문자열)입니다. Datastore는 JSON 직렬화를 blob으로 저장합니다. 기본적으로 색인이 생성되지 않습니다.
선택적 키워드 인수: compressed.
PickleProperty 값은 Python pickle 프로토콜을 사용하여 직렬화할 수 있는 Python 객체(예: 목록, 사전 또는 문자열)입니다. Datastore는 pickle 직렬화를 blob으로 저장합니다. 기본적으로 색인이 생성되지 않습니다.
선택적 키워드 인수: compressed.
GenericProperty 일반 값
대부분 Expando 클래스에서 사용되지만 명시적으로 사용할 수도 있습니다. 값 유형은 int, long, float, bool, str, unicode, datetime, Key, BlobKey, GeoPt, User, None일 수 있습니다.
ComputedProperty 사용자 정의 함수에 의해 다른 속성에서 계산된 값입니다. (계산된 속성을 참조하세요.)

이러한 속성 중 일부에는 선택적 키워드 인수인 compressed가 포함됩니다. 속성에 compressed=True가 있으면 데이터는 디스크에서 gzip을 통해 압축됩니다. 소비 공간이 줄어들지만 쓰기 및 읽기 작업을 수행할 때 인코딩/디코딩을 위해 CPU가 필요합니다.

압축과 압축 해제는 모두 '지연' 작업입니다. 압축된 속성 값은 사용자가 이를 처음에 액세스할 때만 압축 해제됩니다. 압축된 속성 값을 포함하는 항목을 읽고, 압축된 속성에 액세스하지 않고 이를 다시 쓰면, 압축 해제와 압축이 전혀 수행되지 않습니다. 컨텍스트 내 캐시도 이러한 지연 방식을 따르지만, memcache는 항상 압축된 속성의 압축된 값을 저장합니다.

압축에 필요한 추가 CPU 시간 때문에, 일반적으로는 압축하지 않으면 데이터가 너무 큰 경우에만 압축된 속성을 사용하는 것이 가장 좋습니다. 이미지 및 기타 미디어 데이터의 경우는 일반적으로 gzip 기반 압축이 효율적이지 않습니다. 이러한 형식은 미디어별 압축 알고리즘(예: JPEG 이미지)을 사용하여 이미 압축되어 있기 때문입니다.

속성 옵션

대부분의 속성 유형에는 일부 표준 인수가 지원됩니다. 첫 번째는 속성의 Datastore 이름을 지정하는 선택적인 위치 인수입니다. 이를 사용하면 애플리케이션의 관점과 달리 Datastore에서 다른 이름을 속성에 지정할 수 있습니다. 예를 들어 코드에서는 더 길고 의미 있는 이름을 사용하더라도 Datastore가 축약된 속성 이름을 사용하도록 허용함으로써 Datastore에서 저장 공간을 줄일 수 있습니다. 예를 들면 다음과 같습니다.

class Employee(ndb.Model):
    full_name = ndb.StringProperty('n')
    retirement_age = ndb.IntegerProperty('r')

항목당 많은 값이 예상되는 반복된 속성의 경우 특히 유용합니다.

또한 대부분의 속성 유형에서는 다음과 같은 키워드 인수가 지원됩니다.

인수 유형 기본값 설명
indexed bool 일반적으로 True Datastore 색인에 속성을 포함시킵니다. False인 경우 값을 쿼리할 수 없지만, 쓰기가 더 빨라집니다. 모든 속성 유형에서 색인 생성이 지원되지는 않습니다. 이러한 유형에서 indexedTrue로 설정하면 실패합니다.
색인이 생성되지 않은 속성은 색인이 생성된 속성보다 쓰기 작업 비용이 낮습니다.
repeated bool False 속성 값은 기본 유형의 값을 포함하는 Python 목록입니다(반복 속성 참조).
required=True 또는 default=True와 함께 사용할 수 없습니다.
required bool False 속성에 값이 지정되어 있어야 합니다.
default 속성의 기본 유형 없음 None이 명시적으로 지정된 경우 속성의 기본값입니다.
choices 기본 유형의 값 목록 None 허용 가능한 값의 선택적 목록입니다.
validator 함수 None 값을 검증하고 선택적으로 강제할 수 있는 선택적인 함수입니다. 인수((prop, value))를 사용해서 호출되고 (선택적으로 강제된) 값을 반환하거나 예외를 일으킵니다. 강제된 값에서 함수를 다시 호출하면 값이 추가로 수정되지 않습니다. 예를 들어 value.strip() 또는 value.lower()를 반환할 수 있지만 value + '$'를 반환할 수 없습니다. 또한 '변경 없음'을 의미하는 None을 반환할 수 있습니다. 속성 서브클래스 쓰기도 참조하세요.
verbose_name 문자열 None jinja2와 같이 웹 양식 프레임워크에서 사용할 선택적인 HTML 레이블입니다.

반복 속성

repeated=True가 포함된 모든 속성은 반복 속성이 됩니다. 이 속성은 단일 값 대신 기본 유형의 값 목록을 사용합니다. 예를 들어 IntegerProperty(repeated=True)로 정의된 속성의 값은 정수 목록입니다.

Datastore는 이러한 속성에 대해 여러 값을 확인할 수 있습니다. 각 값에 대해 개별 색인 레코드가 생성됩니다. 이것은 쿼리 시맨틱스에 영향을 줍니다. 예시를 보려면 반복 속성 쿼리를 참조하세요.

이 예에는 반복 속성이 사용됩니다.

class Article(ndb.Model):
    title = ndb.StringProperty()
    stars = ndb.IntegerProperty()
    tags = ndb.StringProperty(repeated=True)
...
article = Article(
    title='Python versus Ruby',
    stars=3,
    tags=['python', 'ruby'])
article.put()

이렇게 하면 다음과 같은 내용의 Datastore 항목이 생성됩니다.

assert article.title == 'Python versus Ruby'
assert article.stars == 3
assert sorted(article.tags) == sorted(['python', 'ruby'])

tags 속성을 쿼리하면 이 항목은 'python' 또는 'ruby' 중 하나에 필요한 쿼리를 충족합니다.

반복 속성을 업데이트할 때는 이를 새 목록에 할당하거나 기존 목록을 변형시킬 수 있습니다. 새 목록을 할당할 때는 목록 항목의 유형이 즉시 검증됩니다. 잘못된 항목 유형(예: [1, 2]art.tags에 할당)은 예외를 발생시킵니다. 목록을 변형할 때는 변경사항이 즉시 검증되지 않습니다. 대신 사용자가 Datastore에 항목을 기록할 때 값이 검증됩니다.

Datastore에서는 반복되는 속성의 목록 항목 순서를 유지하므로 순서에 의미를 부여할 수 있습니다.

날짜 및 시간 속성

날짜 및 시간 관련 값을 정렬할 때는 세 가지 속성 유형을 사용할 수 있습니다.

  • DateProperty
  • TimeProperty
  • DateTimeProperty

이러한 속성 유형은 표준 Python datetime 모듈의 해당 클래스(date, time, datetime)에 속하는 값을 사용합니다. 세 가지 유형 중 가장 일반적인 유형인 DateTimeProperty는 달력 날짜 및 시간을 모두 나타냅니다. 다른 유형은 날짜만 필요한 경우(예: 생일) 또는 시간만 필요한 경우(예: 회의 시간)와 같은 특별한 목적에 유용할 수 있습니다. 기술적인 이유로 인해 DatePropertyTimePropertyDateTimeProperty의 서브클래스이지만 이러한 상속 관계에 의존해서는 안 됩니다. 이 관계는 datetime 모듈 자체로 정의된 기본 클래스 사이의 상속 관계와 다릅니다.

이러한 각 속성에는 2개의 추가 불리언 키워드 옵션이 포함되어 있습니다.

옵션 설명
auto_now_add 항목이 생성될 때 현재 날짜/시간으로 속성을 설정합니다. 이 속성은 수동으로 재정의할 수 있습니다. 항목이 업데이트될 때는 속성이 변경되지 않습니다. 이 동작에는 auto_now를 사용합니다.
auto_now 항목이 생성될 때 그리고 업데이트될 때마다 현재 날짜/시간으로 속성을 설정합니다.

이러한 옵션은 repeated=True와 함께 사용할 수 없습니다. 두 가지 모두 기본값은 False입니다. 두 항목 모두 True로 설정된 경우 auto_now가 우선 적용됩니다. auto_now_add=True가 포함된 속성의 값을 재정의할 수 있지만 auto_now=True가 포함된 속성의 값을 재정의할 수 없습니다. 항목이 기록될 때까지 자동 값이 생성되지 않으므로, 이러한 옵션은 동적 기본값을 제공하지 않습니다. (이러한 세부정보는 이전 db API와 다릅니다.)

구조화된 속성

모델의 속성을 구성할 수 있습니다. 예를 들어 각 내부 구조를 포함하여 주소 목록이 포함된 Contact 모델 클래스를 정의할 수 있습니다. 구조화된 속성(StructuredProperty 유형)을 사용하면 가능합니다. 예를 들면 다음과 같습니다.

class Address(ndb.Model):
    type = ndb.StringProperty()  # E.g., 'home', 'work'
    street = ndb.StringProperty()
    city = ndb.StringProperty()

...

class Contact(ndb.Model):
    name = ndb.StringProperty()
    addresses = ndb.StructuredProperty(Address, repeated=True)

...

guido = Contact(
    name='Guido',
    addresses=[
        Address(
            type='home',
            city='Amsterdam'),
        Address(
            type='work',
            street='Spear St',
            city='SF')])

guido.put()

이러면 다음과 같은 속성을 포함하는 단일 Datastore 항목이 생성됩니다.

assert guido.name == 'Guido'
addresses = guido.addresses
assert addresses[0].type == 'home'
assert addresses[1].type == 'work'
assert addresses[0].street is None
assert addresses[1].street == 'Spear St'
assert addresses[0].city == 'Amsterdam'
assert addresses[1].city == 'SF'

이러한 항목을 다시 읽으면 원래 Contact 항목이 정확하게 다시 구성됩니다. Address 인스턴스는 모델 클래스와 동일한 구문을 통해 정의되더라도 완전한 항목이 아닙니다. 이러한 항목은 Datastore에서 자신의 고유 키를 갖고 있지 않습니다. 이러한 항목은 자신이 속하는 Contact 항목과 별개로 검색될 수 없습니다. 하지만 애플리케이션은 자신의 개별 필드 값을 쿼리할 수 있습니다. 구조화된 속성 값 필터링을 참조하세요. address.type, address.street, address.city는 Datastore의 관점에서 병렬 배열로 보이지만 NDB 라이브러리는 이러한 관점을 숨기고 해당 Address 인스턴스 목록을 구성합니다.

구조화된 속성에는 일반적인 속성 옵션을 지정할 수 있습니다(indexed 제외). 이 경우에서 Datastore 이름은 두 번째 위치 인수입니다. 첫 번째는 하위 구조를 정의하는 데 사용되는 모델 클래스입니다.

하위 구조의 내부 속성을 쿼리할 필요가 없으면 로컬 구조화 속성(LocalStructuredProperty)을 대신 사용할 수 있습니다. 위 예시에서 StructuredPropertyLocalStructuredProperty로 바꾸면 Python 코드 동작은 동일하지만 Datastore는 주소마다 불투명한 blob만 확인합니다. 예시에서 생성된 guido 항목은 다음과 같이 저장됩니다.

name = 'Guido'
address = <opaque blob for {'type': 'home', 'city': 'Amsterdam'}>
address = <opaque blob for {'type': 'work', 'city': 'SF',
                              'street': 'Spear St'}>

항목은 다시 올바르게 읽힙니다. 이 유형의 속성은 항상 색인이 생성되지 않기 때문에 주소 값을 쿼리할 수 없습니다.

계산된 속성

계산된 속성(ComputedProperty)은 애플리케이션에서 제공된 함수로 다른 속성 값에서 값을 계산하는 읽기 전용 속성입니다. 계산된 속성은 일반 속성에서 지원되는 유형만 지원합니다. 계산된 값이 Datastore에 기록되어 Datastore 뷰어에서 값을 쿼리 및 표시할 수 있지만 Datastore에서 항목을 다시 읽을 때는 저장된 값이 무시됩니다. 대신 값이 요청될 때마다 함수를 호출하여 값을 다시 계산합니다. 예를 들면 다음과 같습니다.

class SomeEntity(ndb.Model):
    name = ndb.StringProperty()
    name_lower = ndb.ComputedProperty(lambda self: self.name.lower())

...

entity = SomeEntity(name='Nick')
entity.put()

다음 속성 값으로 항목을 저장합니다.

assert entity.name == 'Nick'
assert entity.name_lower == 'nick'

이름을 'Nickie'로 바꾸고 name_lower 값을 요청하면 'nickie'가 반환됩니다.

entity.name = 'Nick'
assert entity.name_lower == 'nick'
entity.name = 'Nickie'
assert entity.name_lower == 'nickie'

Google 프로토콜 RPC 메시지 속성

Google 프로토콜 RPC 라이브러리는 구조화된 데이터에 Message 객체를 사용합니다. 이러한 객체는 RPC 요청, 응답 또는 기타 항목을 나타낼 수 있습니다. NDB는 Google 프로토콜 RPC Message객체를 항목 속성으로 저장하는 데 필요한 API를 제공합니다. Message 서브클래스를 정의한다고 가정해보겠습니다.

from protorpc import messages
...
class Note(messages.Message):
    text = messages.StringField(1, required=True)
    when = messages.IntegerField(2)

NDB msgprop API를 사용하여 Datastore에 Note 객체를 항목 속성 값으로 저장할 수 있습니다.

from google.appengine.ext import ndb
from google.appengine.ext.ndb import msgprop
...
class NoteStore(ndb.Model):
    note = msgprop.MessageProperty(Note, indexed_fields=['when'])
    name = ndb.StringProperty()
...
my_note = Note(text='Excellent note', when=50)

ns = NoteStore(note=my_note, name='excellent')
key = ns.put()

new_notes = NoteStore.query(NoteStore.note.when >= 10).fetch()

필드 이름을 쿼리하려면 색인이 생성되어 있어야 합니다. indexed_fields 매개변수를 사용하여 색인이 생성될 필드 이름 목록을 MessageProperty에 지정할 수 있습니다.

MessageProperty는 일부 옵션을 제외한 다양한 속성 옵션을 지원합니다. 지원되는 옵션은 다음과 같습니다.

  • name
  • repeated
  • required
  • default
  • choices
  • validator
  • verbose_name

메시지 속성은 indexed 속성 옵션을 지원하지 않으므로 Message 값에 색인을 생성할 수 없습니다. (메시지의 필드는 위에 설명된 대로 색인을 생성할 수 있습니다.)

중첩된 메시지(MessageField 사용)도 작동합니다.

class Notebook(messages.Message):
    notes = messages.MessageField(Note, 1, repeated=True)
...
class SignedStorableNotebook(ndb.Model):
    author = ndb.StringProperty()
    nb = msgprop.MessageProperty(
        Notebook, indexed_fields=['notes.text', 'notes.when'])

MessageProperty에는 특수 속성 옵션인 protocol이 있습니다. 이 옵션은 메시지 객체가 Datastore에 직렬화되는 방식을 지정합니다. 값은 protorpc.remote.Protocols 클래스에서 사용된 것처럼 프로토콜 이름입니다. 지원되는 프로토콜 이름은 protobufprotojson이고 기본값은 protobuf입니다.

msgpropEnumProperty도 정의합니다. 항목에 protorpc.messages.Enum 값을 저장하는 데 이 속성 유형을 사용할 수 있습니다. 예를 들면 다음과 같습니다.

class Color(messages.Enum):
    RED = 620
    GREEN = 495
    BLUE = 450
...
class Part(ndb.Model):
    name = ndb.StringProperty()
    color = msgprop.EnumProperty(Color, required=True)
...
p1 = Part(name='foo', color=Color.RED)
print p1.color  # prints "RED"

EnumProperty는 값을 정수로 저장합니다. 실제로 EnumPropertyIntegerProperty의 서브클래스입니다. 즉, 이미 저장된 항목을 수정할 필요 없이 열거형 값의 이름을 바꿀 수 있지만, 번호는 다시 지정할 수 없습니다.

EnumProperty는 다음과 같은 속성 옵션을 지원합니다.

  • name
  • indexed
  • repeated
  • required
  • default
  • choices
  • validator
  • verbose_name

NDB 항목 모델 정보

NDB 항목 모델은 속성을 정의할 수 있습니다. 항목 속성은 데이터 저장을 위한 구조화된 방법인 Python 클래스의 데이터 멤버와 다소 비슷하지만, 데이터베이스 스키마의 필드와도 다소 비슷합니다.

일반적인 애플리케이션은 일부 속성 클래스 속성이 포함된 Model에서 상속되는 클래스를 정의하여 데이터 모델을 정의합니다. 예를 들면 다음과 같습니다.


from google.appengine.ext import ndb
...
class Account(ndb.Model):
    username = ndb.StringProperty()
    userid = ndb.IntegerProperty()
    email = ndb.StringProperty()

여기서 username, userid, emailAccount 속성입니다.

이것들은 몇 가지 다른 속성 유형입니다. 일부는 날짜 및 시간을 나타내기에 좋으며, 편리한 자동 업데이트 기능을 갖고 있습니다.

애플리케이션은 속성에 옵션을 지정하여 속성 동작을 조정할 수 있습니다. 이것들은 검증을 용이하게 해주고, 기본값을 설정하고, 쿼리 색인 생성을 변경할 수 있습니다.

모델은 보다 복잡한 속성을 포함할 수 있습니다. 반복 속성은 목록과 비슷합니다. 구조화된 속성은 객체와 비슷합니다. 읽기 전용 계산된 속성은 함수를 통해 정의되며, 하나 이상의 다른 속성에서 속성을 쉽게 정의할 수 있게 해줍니다. Expando 모델은 속성을 동적으로 정의할 수 있습니다.