2011-04-14 42 views
0

相關部分:谷歌AppEngine上告訴我,我的int是不是代碼的一個int

pk = int(pk)        
logging.info('pk: %r :: %s', pk, type(pk)) 
instance = models.Model.get_by_id(int(pk))  

從日誌消息輸出上述

pk: 757347 :: <type 'int'> 

堆棧跟蹤:

Traceback (most recent call last): 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 634, in __call__ 
    handler.get(*groups) 
    File "/base/data/home/apps/<myapp>/<version>/scrape.py", line 61, in get 
    instance = models.Model.get_by_id(int(pk)) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1212, in get_by_id 
    return get(keys[0], config=config) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1434, in get 
    model = cls1.from_entity(entity) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 1350, in from_entity 
    instance = cls(None, _from_entity=True, **entity_values) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 890, in __init__ 
    prop.__set__(self, value) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 593, in __set__ 
    value = self.validate(value) 
    File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2967, in validate 
    % (self.name, type(value).__name__)) 
BadValueError: Property pk must be an int or long, not a unicode 

如果我在這裏做錯了什麼,任何人都有想法嗎?

注:去除代碼的最後一行int沒有區別(這是第一個版本)。

另外,代碼在dev_appserver.py上沒有問題。

+0

我覺得問題不在最後一行。它在logging.info – 2011-04-14 09:05:57

+0

對不起,問題不在於日誌記錄。你確定數據存儲中存在具有757347 ID的實體嗎? – 2011-04-14 09:21:52

+0

@Abdul Kader:如果該項不存在,它應該返回「無」。但我嘗試刪除實體,並沒有任何區別。 – Wolph 2011-04-14 11:34:51

回答

4

您的模型是否有屬性'pk',現在是一個IntegerProperty(),但之前是一個StringProperty(),並且具有ID 757347的實體與舊版本的模型一起保存?

+1

不,但我使用批量加載器上傳數據,所以很有可能它沒有作爲整數加載,我會檢查並回復給您。 – Wolph 2011-04-14 11:33:42

+1

對不起,我一直很忙。但是......你的答案就在這個點上。刪除項目(編輯/保存通常不可能)稍微有點棘手,但它工作。 非常感謝您的幫助。 – Wolph 2011-04-19 23:12:10

+0

+1非常幫助解答謝謝 – Anthony 2013-03-20 22:04:33

2

爲您的pk IntegerProperty創建一個自定義驗證器。

我認爲@ saxon-druce對什麼是失敗有正確的想法。

您正在從數據存儲中接收實體,而from_entity函數會將實體中的數據應用於db.Model的初始化程序。

調用validate是google/appengine/ext/db/__init__.py

從SDK

class IntegerProperty(Property): 
    """An integer property.""" 

    def validate(self, value): 
    """Validate integer property. 

    Returns: 
     A valid value. 

    Raises: 
     BadValueError if value is not an integer or long instance. 
    """ 
    value = super(IntegerProperty, self).validate(value) 
    if value is None: 
     return value 





    if not isinstance(value, (int, long)) or isinstance(value, bool): 
     raise BadValueError('Property %s must be an int or long, not a %s' 
          % (self.name, type(value).__name__)) 
    if value < -0x8000000000000000 or value > 0x7fffffffffffffff: 
     raise BadValueError('Property %s must fit in 64 bits' % self.name) 
    return value 

    data_type = int 

創建試圖解析字符串作爲一個int自己平凡的驗證。 最終你可能會想要在所有這些實體中應用一個映射器,以使它們全部達到當前的模式。

驗證器在value = super(IntegerProperty, self).validate(value) 之內調用,因此該值應該在適當的時候作爲int使用。

實施例驗證

def str_int_validator(value): 
    if isinstance(value, basestring): 
     if value.isdigit(): 
      return int(value) 
     else: 
      raise db.BadValueError("Property expected str or int got %r" % value) 
    else: 
     return value 

class Foo(db.Model): 

    pk = db.IntegerProperty(validator=str_int_validator) 

此代碼尚未經過測試。

+0

哇,很好的答案。我會馬上試一試:) – Wolph 2011-04-14 11:33:59

+0

不幸的是,添加自定義驗證程序並未解決問題。我試圖刪除違規的行,因爲它們似乎無論如何都被損壞了 – Wolph 2011-04-15 15:25:08

+0

這個問題的確如saxon-druce描述的那樣。謝謝您的傑出答案,但我必須在信用到期時給予獎勵,saxon-druce是第一個,並且此代碼無法爲我解決問題。至少+1我:) – Wolph 2011-04-19 23:13:47

1

刪除一個實體/表中的所有元素,然後嘗試通過csv/bulkloader上傳新值後,我得到了相同的錯誤消息。

的解決方案是

import_transform: transform.none_if_empty(int) 

添加以下行到屬性定義在YAML文件爲批量加載器。

相關問題