2019年4月21日 星期日

[GAE] Google Cloud Datastore中的Entity與Key的關係

  這篇文章我們將接續[GAE] 使用NDB client library建立Model,先前已經學會建立Model,那接下來要介紹Google Cloud Datastore裡的entity實體與key。


  entity是指能儲存在Google Cloud Datastore的物件,每個存在Google Cloud Datastore的entity都具有一獨特的key。

 1. 生成 entities:
  entities是能儲存在Cloud Datastore的物件,要產生entities首先要定義model,model相當於entity的結構,這裡我們定義了Person model作為例子。
from google.appengine.ext import ndb

class Person(ndb.Model):
    name = ndb.StringProperty()
    age = ndb.IntegerProperty()
  生成 一Person entity,並使用put()將這個entity存進Datastore中。
p = Person(name='Tom', age=12)
k = p.put()
  put()方法會回傳key值,key可用來從Datastore中讀取對應entity。

2. 設定 entities 的屬性(properties):
  有三種方式:
## 1 ##
p = Person(name='Tom', age=42)

## 2 ##
p = Person()
p.name = 'Tom'
p.age = 12

## 3 ##
p = Person()
p.populate(name='Tom', age=12)
若放了一個不符合其屬性的值,例如 ndb.IntegerProperty()卻存字串,會raises an exception 出錯。

3. 使用key讀取entities:
  持有key時可以使用get()方法能讀取entity。
tom = k.get()
  key還有kind()、id()兩方法,分別能回傳entity的kind和identifier。
kind_string = k.kind() # return 'Person'
ident = k.id()
  key的urlsafe()方法會回傳類似這樣的字串"agVoZWxsb3IPCxIHQWNjb3VudBiZiwIM",適合安插在URL用,之後也可以用這個字串重新得到key。但要注意,這個字串不是加密後的產物,隨便就能從 ndb.Key(urlsafe=url_string).kind()或id() 得到kind與id資訊,所以重要資料別將這個字串就直接安插在URL裡。
url_string = k.urlsafe()
k = ndb.Key(urlsafe=url_string)

4. 更新entities:
p = k.get()
p.age = 13
p.put()  ## 要記得put()

5. 刪除entities:
k.delete() ## = p.key.delete()

如果需要刪除大量entities時,官方建議使用Cloud Dataflow,請參考這裡:https://cloud.google.com/datastore/docs/bulk-delete

6. 大批處理:
list_of_keys = ndb.put_multi(list_of_entities)
list_of_entities = ndb.get_multi(list_of_keys)
ndb.delete_multi(list_of_keys)



  每一個Entity都具有一獨特的key,key則由兩要素構成:
    (1) kind:是entity屬於的model名,但可透過override _get_kind()這個class method改回傳的字串內容。
    (2) identifier:可以設定id屬性決定identifier或由Cloud datastore自動生成一整數值。
account = Account(
    username='Sandy', userid=1234, email='sandy@example.com',
    id='sandy@example.com')

return account.key.id()  # returns 'sandy@example.com'
    
  1. 設定key:
account.key = ndb.Key('Account', 'sandy@example.com')

# You can also use the model class object itself, rather than its name,
# to specify the entity's kind:
account.key = ndb.Key(Account, 'sandy@example.com')
  
  2. 設定key的parent key:
class Revision(ndb.Model):
    message_text = ndb.StringProperty()

ndb.Key('Account', 'sandy@example.com', 'Message', 123, 'Revision', '1')

  ('Account', 'sandy@example.com')、('Message', 123)和('Revision', '1')是kind-id各代表key,並依序下來的繼承關係,最後得到的是('Revision', '1')這個key。(Notice that Message is not a model class; it is used only as a way to group revisions, not to store data.)
  上面的程式碼意思等同
ndb.Key('Revision', '1', parent=ndb.Key(
    'Account', 'sandy@example.com', 'Message', 123))

ndb.Key('Revision', '1', parent=ndb.Key(
    'Message', 123, parent=ndb.Key('Account', 'sandy@example.com')))

  3. 由parent key上到下建立entity:
account_key = ndb.Key(Account, 'sandy@example.com')

# Ask Datastore to allocate an ID.
new_id = ndb.Model.allocate_ids(size=1, parent=account_key)[0]

# Datastore returns us an integer ID that we can use to create the message key
message_key = ndb.Key('Message', new_id, parent=account_key)

# Now we can put the message into Datastore
initial_revision = Revision(
    message_text='Hello', id='1', parent=message_key)
initial_revision.put()

message_key = initial_revision.key.parent() ## 可由parent()得到上層key



參考資料:
  1. 官方文件:
https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entities
https://cloud.google.com/appengine/docs/standard/python/ndb/creating-entity-keys


沒有留言:

張貼留言