Class Model NDB

Class yang diwarisi dari class Model merepresentasikan struktur entity yang disimpan di Datastore. Aplikasi menentukan class model untuk menunjukkan struktur entity-nya, lalu membuat instance class model tersebut untuk membuat entity. Semua class model harus mewarisi (langsung atau tidak langsung) dari Model.

Halaman ini memiliki dokumentasi referensi API. Untuk ringkasan, lihat Entity dan Kunci NDB.

Pengantar

Class yang mewarisi dari Model mendeskripsikan entity Datastore.

Semua class model harus mewarisi (langsung atau tidak langsung) dari Model. Penetapan langsung dalam definisi class model dapat digunakan untuk mendeklarasikan struktur model:

from google.appengine.ext import ndb

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

Sekarang kita dapat membuat entity Person dan menulisnya ke Datastore:

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

Nilai yang ditampilkan dari put() adalah Kunci, yang dapat digunakan untuk mengambil entity yang sama di lain waktu:

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

Untuk mengupdate entity, cukup ubah atributnya dan tuliskan kembali (perhatikan bahwa hal ini tidak akan mengubah kunci):

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

Kita juga dapat menghapus entity (dengan menggunakan kunci):

k.delete()

Definisi properti dalam isi class memberi tahu sistem nama dan jenis kolom yang akan disimpan di Datastore, apakah kolom tersebut harus diindeks, nilai defaultnya, dan banyak lagi. Terdapat berbagai Jenis properti.

Jenis ini biasanya sama dengan nama class (tidak termasuk nama modul atau cakupan induk lainnya). Untuk mengganti jenis (berguna untuk perubahan skema), tentukan metode class dengan nama _get_kind(), sebagai berikut:

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

Aplikasi tidak boleh mendefinisikan dua class model dengan jenis yang sama, meskipun class tersebut berada di modul berbeda. Jenis aplikasi dianggap sebagai "namespace" global.

Subclass Model dapat menentukan hook pra-panggilan dan pasca-panggilan untuk sebagian besar operasi (get, put, delete, arrange_ids).

Konstruktor

Aplikasi biasanya tidak akan memanggil Model(), tetapi kemungkinan akan memanggil konstruktor class yang diwarisi dari Model. Tindakan ini akan membuat instance baru dari model ini, yang juga dikenal sebagai entity.

Entity yang baru dibuat tidak secara otomatis ditulis ke Datastore. Untuk mewujudkannya, entity tersebut harus ditulis ke Datastore menggunakan panggilan eksplisit ke put().

Argumen:

Subclass Model mendukung argumen-argumen kata kunci ini:

key
Instance key untuk model ini. Jika parameter key digunakan, id dan parent harus None (default).
id
ID kunci untuk model ini. Jika id digunakan, kunci harus berupa None (default).
parent
Instance key untuk model induk atau None untuk model tingkat atas. Jika parent digunakan, key harus None.
namespace
Namespace yang akan digunakan untuk entity ini, atau None (default) untuk menggunakan namespace saat ini. Jika namespace digunakan, key harus None.

Aplikasi juga dapat menggunakan pemetaan argumen kata kunci untuk properti model. Misalnya, kode berikut berfungsi:

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

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

Anda tidak dapat dengan mudah menentukan properti bernama "key", "id", "parent", atau "namespace". Jika Anda meneruskan, misalnya, key="foo" dalam konstruktor atau panggilan populate(), kunci entity akan ditetapkan, bukan atribut properti yang bernama "key".

Catatan: Jika Anda mengganti konstruktor di subclass Model, berhati-hatilah karena konstruktor juga dipanggil secara implisit dalam beberapa kasus, dan pastikan Anda mendukung konstruktor tersebut panggilan. Saat entity dibaca dari Datastore, entity kosong pertama kali dibuat dengan memanggil konstruktor tanpa argumen, setelah itu nilai kunci dan properti akan ditetapkan satu per satu. Saat get_or_insert() atau get_or_insert_async() membuat instance baru, instance akan melewati **constructor_args ke konstruktor, dan menetapkan kunci setelahnya.

Metode Class

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

Mengalokasikan rentang ID kunci untuk class model ini.

Argumen

size
Jumlah ID yang akan dialokasikan. size atau max dapat ditentukan, tidak keduanya.
max
ID maksimum untuk dialokasikan. size atau max dapat ditentukan, tidak keduanya.
parent
Kunci induk yang akan digunakan untuk mengalokasikan ID.
**ctx_options
Opsi konteks

Menampilkan tuple dengan (start, end) untuk rentang yang dialokasikan, inklusif.

Aplikasi tidak dapat memanggil allocate_ids() dalam transaksi.

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

Versi asinkron allocate_ids.

Menampilkan objek Future yang hasilnya adalah tuple dengan (start, end) untuk rentang yang dialokasikan, inklusif.

get_by_id(id, parent=None, app=None, namespace=None, **ctx_options)
Menampilkan entitas berdasarkan ID. Ini benar-benar penyederhanaan untuk Key(cls, id).get().

Argumen

id
ID kunci string atau bilangan bulat.
parent
Kunci induk dari model yang akan didapatkan.
app (argumen kata kunci)
ID aplikasi. Jika tidak ditentukan, akan mendapatkan data untuk aplikasi saat ini.
namespace (argumen kata kunci)
Namespace. Jika tidak ditentukan, akan mendapatkan data untuk namespace default.
**ctx_options
Opsi konteks

Menampilkan instance model atau None jika tidak ditemukan.

get_by_id_async(id, parent=None, app=None, namespace=None, **ctx_options)
Versi asinkron get_by_id.

Menampilkan objek Future yang hasilnya adalah instance model atau None jika tidak ditemukan.

get_or_insert(key_name, parent=None, app=None, namespace=None, context_options=None, **constructor_args)
Mengambil entitas yang sudah ada atau membuat entitas baru secara transaksi.

Argumen

key_name
Nama kunci (yaitu, ID kunci string) yang akan diambil atau dibuat. \
parent
Kunci entitas induk, jika ada.
app
ID aplikasi. Jika tidak ditentukan, akan mendapatkan data untuk aplikasi saat ini.
namespace
Namespace. Jika tidak ditentukan, akan mendapatkan data untuk namespace default.
context_options
Opsi konteks

Fungsi ini juga menggunakan argumen kata kunci untuk diteruskan ke konstruktor class model jika instance untuk nama kunci yang ditentukan belum ada. Jika instance dengan key_name yang disediakan dan induk sudah ada, argumen ini akan dihapus.

Menampilkan instance class Model yang ada dengan nama kunci dan induk yang ditentukan atau yang baru saja dibuat.

Fungsi ini menggunakan transaksi. Jika kode yang memanggil fungsi ini sudah ada dalam transaksi, fungsi ini akan mencoba menggunakan kembali transaksi yang ada. Jika entity group fungsi ini tidak kompatibel dengan transaksi yang ada, hal ini dapat menyebabkan error.

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

Ini adalah versi asinkron dari get_or_insert.

Metode ini menampilkan objek Future yang hasilnya adalah instance class Model yang sudah ada dengan nama kunci dan induk yang ditentukan atau yang baru saja dibuat.

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

Membuat objek Query untuk class ini seperti yang dijelaskan dalam Kueri.

Argumen kata kunci distinct adalah penyederhanaan untuk proyeksi group_by. Semua argumen kata kunci lainnya akan diteruskan ke Konstruktor kueri.

Jika argumen posisi diberikan, argumen tersebut akan digunakan untuk menyiapkan filter awal.

Mengembalikan objek Query.

Metode Instance

populate(**constructor_options)

Menetapkan nilai properti entity. Argumen kata kuncinya otomatis mengenali nama properti dengan cara yang sama seperti yang dilakukan konstruktor.

put(**ctx_options)

Menulis data entity ke Datastore. Menampilkan Kunci entity.

Argumen

**ctx_options
Opsi konteks
put_async(**ctx_options)

Menulis data entity secara asinkron ke Datastore. Mengembalikan objek Future. Hasil objek Future akan menjadi Kunci entity.

Argumen

**ctx_options
Opsi konteks
to_dict(include=all, exclude=None)

Mengembalikan dict yang berisi nilai properti model. Nilai properti untuk StructuredProperty dan LocalStructuredProperty dikonversi secara rekursif menjadi kamus.

Argumen:

include
Daftar properti opsional yang akan disertakan. Default: all.
exclude
Daftar properti opsional yang akan dikecualikan. Jika ada tumpang-tindih antara include dan exclude, maka exclude akan "dimenangkan".

Catatan: Jika nilai properti adalah objek yang dapat diubah (misalnya daftar yang mewakili properti berulang, atau dikte atau daftar yang disimpan dalam JsonProperty), kecuali jika nilainya dikonversi secara eksplisit (misalnya dalam kasus StructuredProperty), objek yang sama akan dikembalikan dalam kamus yang disimpan dalam entity. Dalam kasus semacam ini, mengubah kamus akan mengubah entitas, dan sebaliknya.

Data Instance

key
Properti khusus untuk menyimpan kunci Model.

Metode Hook

Subclass Model aplikasi dapat menentukan satu atau beberapa metode ini sebagai metode "hook" sebelum atau sesudah operasi. Misalnya, untuk menjalankan beberapa kode sebelum setiap "get", tentukan metode _pre_get_hook() subclass model. Untuk saran tentang cara menulis fungsi hook, lihat Hook Model.

@classmethod
_pre_allocate_ids_hook(cls, size, max, parent)
Hook yang berjalan sebelum allocate_ids()
@classmethod
_post_allocate_ids_hook(cls, size, max, parent, future)
Hook yang berjalan setelah allocate_ids()
@classmethod
_pre_delete_hook(cls, key)
Hook yang berjalan sebelum delete()
@classmethod
_post_delete_hook(cls, key, future)
Hook yang berjalan setelah delete()
@classmethod
_pre_get_hook(cls, key)
Hook yang berjalan sebelum Key.get() saat mendapatkan entity model ini.
@classmethod
_post_get_hook(cls, key, future)
Hook yang berjalan setelah Key.get() saat mendapatkan entity model ini.
_pre_put_hook(self)
Hook yang berjalan sebelum put()
_post_put_hook(self, future)
Hook yang berjalan setelah put()

Introspeksi

Anda bisa menggunakan metode ini untuk memeriksa properti dan konfigurasi model tertentu. Ini berguna jika Anda menulis library atau fungsi yang menerima beberapa jenis model.

Mencari menurut jenis

Setiap model memiliki jenis yang biasanya sama dengan nama class kecuali jika diganti. Anda dapat menggunakan jenis tersebut untuk menemukan class model terkait menggunakan _lookup_model.

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

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

Perhatikan bahwa _lookup_model hanya berfungsi untuk class model yang telah diimpor oleh aplikasi.

Properti

Anda bisa mendapatkan daftar semua properti yang terkait dengan model menggunakan _properties.

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

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

_properties juga berfungsi untuk instance Expando.

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)}

Instance properti dapat dijadikan introspeksi. Opsi yang diberikan untuk konstruktor tersedia sebagai properti berawalan _.

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

Alias Metode

Setiap metode dalam class Model memiliki alias berawalan _. Misalnya, _put() setara dengan put(). Artinya, Anda dapat memiliki properti dengan nama yang bertentangan dengan nama metode asalkan Anda selalu menggunakan metode berawalan _. Namun, perhatikan bahwa Anda tidak dapat menentukan properti bernama key, parent, atau id di konstruktor.

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.

Jika Anda membuat library pihak ketiga yang berinteraksi dengan model arbitrer, sebaiknya gunakan metode berawalan _.