0

漠然としたタイトルではないと言えば、これをどのように述べるべきか分かりませんでした。try-except-finallyの不思議な挙動

URLからデータを取得してblobstoreに書き込み、データのblob_keyをデータストアのListPropertyに保存するタスクワーカーリクエストハンドラがあります。私はここで明確にするためのコードをsimpliflyしようとしました:

saveDataResultがTrueを返すとき、今私がいる問題は、そのステータスは「成功」に設定されているが、そのblobKeyにプロパティでも、値が含まれていません
class Fetch(webapp2.RequestHandler): 
    def get(self): 

     url = self.request.get('url') 
     itemKey = self.request.get('itemKey') 
     item = MyModel.get(itemKey) 

     try: 
      result = urlfetch.fetch(url=url) 
      if result.status_code == 200: 
       saveDataResult = save_data(result.content, itemKey) 
       if saveDataResult is False: 
        raise Exception('error saving data') 
      else: 
       raise Exception('error fetching data: %s' % result.status_code) 

      item.status = 'success' 
     except Exception: 
      item.status = 'failed' 
     finally: 
      item.put() 

def save_data(data, itemKey) 
    try: 
     #write data to blobstore and get its blob_key... 
     blob_key = files.blobstore.get_blob_key(file_name) 
     item = MyModel.get(itemKey) 
     item.blobKey.append(blob_key) 
     item.put() 

     return True 
    except: 
     return False 

blob_keyが生成され、データが正常に書き込まれました。私はこれが私の人生を救う原因になっているのを見ることができません、助けてください。

+0

'blob_key'(' item.blobKey'ではなく)が値を取得する部分を表示していないか、それとも問題でしょうか? –

+0

'blob_key'はどこで設定しますか? – cheeken

+0

私はそれを追加しましたが、blob_keyが取得できない場合、save_dataはFalseを返すので、それはできません。それが原因ではないと私は確信しています。 – ofko

答えて

2

これ以上の情報がなくても、何が起きているのかを判断することは非常に困難です。

MyModel.get(itemKey)は、get()save_data()の両方で呼ばれています。私はそれがアイテムを表す2つの異なるオブジェクトを返すと推測します。 blobKeyがsave_dataに更新されると、更新はsave_dataにフェッチされたオブジェクトでのみ発生しています。後でそれをそのスコープの外側で調べると、別のオブジェクトが表示されます。

これが正しいかどうかは、MyModel.get()の実装によって異なります。

さらに、item.put()を2回呼び出すことがわかりましたか?したがって

+0

私はget()からsave_dataへのitemのインスタンスをparamとして渡すべきでしょうか?私は今それを試みている。 – ofko

0

問題は、あなたが(2つの異なるオブジェクトを持つため、save_dataに1を上書きしてしまうのフェッチ再びクラスから呼び出されたitem = MyModel.get(itemKey)save_data()を呼び出すときということです)、あなたのモデルのデータストアにデータを全く行っていませんblobkeyは上書きされて格納されます。

クラス内のすべてを実行するか、item = MyModel.get(itemKey)を2回使用しないでください。

1

問題はここに

finally: 
    item.put() 

であるこの単一の呼び出しは、それはアイテムの古いオブジェクトを参照しているためsave_data()によって保存されたデータを上書きします。

私の提案は、あなたがsave_data()すなわちitem.status = 'success' からステータスの更新を行うかそこらあなたが更新されたオブジェクトを取得することができますsave_data()後に来るようにitem = MyModel.get(itemKey)を移動するだろう。