建立Model儲存資料:
model是用來描述entity,就像是SQL裡的表格(table)一樣,而宣告的屬性就像表的field。entity是呼叫ndb.Model subclass的建構子建立,呼叫 put() 儲存。下面的例子是建立一個Account model,裡面有username、userid、email三種屬性。
from google.appengine.ext import ndb
class Account(ndb.Model):
username = ndb.StringProperty()
userid = ndb.IntegerProperty()
email = ndb.StringProperty()
也可以建立能動態追加屬性的entity,須改繼承ndb.Expando:
class FlexEmployee(ndb.Expando):
name = ndb.StringProperty()
age = ndb.IntegerProperty()
employee = FlexEmployee(name='Sandy', location='SF') # age會是None, location是動態追加的屬性
logging.info(employee._properties) # 可查看property
# {
# 'name': StringProperty('name'),
# 'age': IntegerProperty('age'),
# 'location': GenericProperty('location') # GenericProperty用於動態屬性
# }
* 要注意的是使用 FlexEmployee.query(FlexEmployee.location == 'SF')是搜不到東西的,因為該類沒有location屬性的屬性對象。若要以動態屬性進行搜尋要寫像這樣: FlexEmployee.query(ndb.GenericProperty('location') == 'SF')。
使用Model hooks:
有時我們在作動作時固定都會再作些預處理或後處理,例如讀取資料庫的資料時,我們會先查看資料是否在cache中,而NDB提供我們輕量方便的hook方法來完成這樣的動作。hook可用於以下方面:
1. 查詢緩存
2. 旁聽每個用戶的存儲活動
3. 模仿數據庫觸發器 (mimicking database triggers)
範例:
class Friend(ndb.Model):
name = ndb.StringProperty()
def _pre_put_hook(self):
_notify('Gee wiz I have a new friend!')
@classmethod
def _post_delete_hook(cls, key, future):
_notify('I have found occasion to rethink our friendship.')
##################################
f = Friend()
f.name = 'Carole King'
f.put() # _pre_put_hook is called
fut = f.key.delete_async() # _post_delete_hook not yet called
fut.get_result() # _post_delete_hook is called
* asynchronous post-hook要由check_result(), get_result()來觸發
Entity Property:
一個entity可有20000個properties,NDB提供了以下儲存屬性:
屬性
|
說明
|
IntegerProperty
|
64-bit int long
|
FloatProperty
|
雙精準度浮點數
|
BooleanProperty
|
boolean
|
StringProperty
|
短字串(上限是1500bytes),資料儲存庫會將短字串建立索引,可用於篩選器和排序順序。系統會將str值認定為使用ascii編碼而成的文字,且會在儲存值之前轉換成unicode值。資料儲存庫會將該值當成unicode值傳回。至於使用其他轉碼器的短字串,則使用unicode值。
|
TextProperty
|
無長度限制的長字串,不會建立索引。arg為unicode或str值。如果arg是str,則會由「encoding」指定的編碼剖析,如果沒有指定編碼則為ascii。
|
BlobProperty
|
未解譯的二進位資料。若設定indexed=True則上限是1500bytes且會建立索引;設定indexed=False則長度無上限但不會建立索引。
|
DateTimeProperty
|
日期與時間 (可設定auto_now_add、auto_now)
|
DateProperty
|
日期
|
TimeProperty
|
時間
|
GeoPtProperty
|
浮點經緯度座標 (ndb.GeoPt)
|
KeyProperty
|
Cloud Datastore Key
|
BlobKeyProperty
|
Blobstore Key
|
StructuredProperty
|
存放model在model裡用
|
LocalStructuredProperty
|
同StructuredProperty,但on-disk representation is an opaque blob and is not indexed (可設定compressed)
|
JsonProperty
|
Value is a Python object (such as a list
or a dict or a string) that is serializable using Python's json module; Cloud
Datastore stores the JSON serialization as a blob. Unindexed by default. (可設定compressed)
|
PickleProperty
|
Value is a Python object (such as a list
or a dict or a string) that is serializable using Python's pickle protocol;
Cloud Datastore stores the pickle serialization as a blob. Unindexed by
default.
|
GenericProperty
|
Generic value,常用在Expando class
|
ComputedProperty
|
Value computed from other properties by a
user-defined function
|
Property內常用的參數:
參數
|
型態
|
預設值
|
說明
|
Indexed
|
bool
|
usually True
|
if False, values cannot be queried but
writes are faster.
|
repeated
|
bool
|
False
|
Any property with repeated=True becomes a
repeated property. The property takes a list of values of the underlying
type, rather than a single value.
|
required
|
bool
|
False
|
一定要有值
|
default
|
值由property決定
|
None
|
預設值
|
choices
|
List of values (值由property決定)
|
None
|
可被輸入的值的list (選單)
|
validator
|
function
|
None
|
Optional function to validate and
possibly coerce the value.
|
verbose_name
|
string
|
None
|
Optional HTML label to use in web form
frameworks like jinja2
|
Writing Property Subclasses:
A Property subclass that implements a specific transformation between user values and serializable values should implement two methods, _to_base_type() and _from_base_type().舉例:IntegerProperty只支援儲存64-bit整數,若我們要存超過此值應要轉存成字串,可以建立一個繼承StringProperty的property subclass來處理。
class LongIntegerProperty(ndb.StringProperty):
def _validate(self, value):
if not isinstance(value, (int, long)):
raise TypeError('expected an integer, got %s' % repr(value))
def _to_base_type(self, value):
return str(value) # Doesn't matter if it's an int or a long
def _from_base_type(self, value):
return long(value) # Always return a long
* _validate():當設定property值時運作。
_to_base_type():當要把entity寫入datastore時運作。
_from_base_type():當要從datastore讀entity時運作。
沒有留言:
張貼留言